Commit 12614635 authored by loring's avatar loring

libsim safe zero copy data transfer and numpy support :

if numpy is found during configure then libsim may be passed
numpy arrays directly. zero-copy transfer are supported via
numpy c-api. a new ownership type is introduced to support
safe zero-copy transfer of data to vtk data arrays. when this
ownership is requested a custom (potentially user provided)
callback is invoked by an internally arranged observer of vtk
data array delete event. the callback should free the memory.
this mechanism can be used in any zero-copy transfer through
libsim where c's free is not the correct function to free the
transfered memory, in the case of python and numpy, we make
use of python's ref counting to ensure the numpy object is not
destroyed until the vtk array is deleted. the numpy object's
ref count incremented (by libsim) as its passed in, libsim
provides a callback which decrements the object's ref count
when the vtk data array is deleted. aside from having to pass
the new ownership flag, this all happens transparently to the
user as it is implemented in libsim's python swig customizations.
If this were to be used in other situations, eg FORTRAN, the user
would be extected to provide the memory management callback.



git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@22880 18c085ea-50e0-402c-830e-de6fd14e8384
parent c0268e21
#*****************************************************************************
#
# Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
# Produced at the Lawrence Livermore National Laboratory
# LLNL-CODE-442911
# All rights reserved.
#
# This file is part of VisIt. For details, see https://visit.llnl.gov/. The
# full copyright notice is contained in the file COPYRIGHT located at the root
# of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the disclaimer below.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the disclaimer (as noted below) in the
# documentation and/or other materials provided with the distribution.
# - Neither the name of the LLNS/LLNL nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
# LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
#*****************************************************************************
# FindNumpy
#
# Check if numpy is installed and configure c-api includes
#
# This module defines
# NUMPY_FOUND, set TRUE if numpy and c-api are available
# NUMPY_INCLUDE_DIR, where to find c-api headers
set(_TMP_PY_OUTPUT)
set(_TMP_PY_RETURN)
exec_program("${PYTHON_EXECUTABLE}"
ARGS "-c 'import numpy; print numpy.get_include()'"
OUTPUT_VARIABLE _TMP_PY_OUTPUT
RETURN_VALUE _TMP_PY_RETURN)
set(NUMPY_INCLUDE_FOUND FALSE)
if(NOT _TMP_PY_RETURN AND EXISTS "${_TMP_PY_OUTPUT}")
set(NUMPY_INCLUDE_FOUND TRUE)
else()
set(_TMP_PY_OUTPUT)
endif()
set(NUMPY_INCLUDE_DIR "${_TMP_PY_OUTPUT}")
#set(NUMPY_INCLUDE_DIR "${_TMP_PY_OUTPUT}" CACHE PATH "Numpy C API headers")
#mark_as_advanced(NUMPY_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NUMPY DEFAULT_MSG NUMPY_INCLUDE_FOUND)
......@@ -539,6 +539,7 @@ PROJECT(VISIT)
#-----------------------------------------------------------------------------
# Set extended platlform defs.
#-----------------------------------------------------------------------------
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMake/)
INCLUDE(${VISIT_SOURCE_DIR}/CMake/SetUpPlatformDefs.cmake)
......
This diff is collapsed.
This diff is collapsed.
......@@ -107,6 +107,7 @@ typedef enum {
#define VISIT_OWNER_SIM 0
#define VISIT_OWNER_VISIT 1
#define VISIT_OWNER_COPY 2
#define VISIT_OWNER_VISIT_EX 3
/* Cell Types */
#define VISIT_CELL_BEAM 0
......@@ -211,7 +212,7 @@ typedef enum {
#define VISIT_IMAGEFORMAT_PNG 2
#define VISIT_IMAGEFORMAT_POVRAY 3
#define VISIT_IMAGEFORMAT_PPM 4
#define VISIT_IMAGEFORMAT_RGB 5
#define VISIT_IMAGEFORMAT_RGB 5
#define VISIT_IMAGEFORMAT_TIFF 6
#ifdef __cplusplus
......
......@@ -53,7 +53,7 @@ int
VisIt_VariableData_free(visit_handle obj)
{
VISIT_DYNAMIC_EXECUTE(VariableData_free,
int, (visit_handle),
int, (visit_handle),
(obj));
}
......@@ -161,6 +161,24 @@ VisIt_VariableData_getDataL(visit_handle obj, int *owner, int *ncomps,
(obj,owner,&dataType,ncomps,ntuples,(void **)ptr));
}
int
VisIt_VariableData_setData(visit_handle obj, int owner, int dataType,
int ncomps, int ntuples, void *ptr)
{
VISIT_DYNAMIC_EXECUTE(VariableData_setData,
int, (visit_handle,int,int,int,int,void*),
(obj,owner,dataType,ncomps,ntuples,ptr));
}
int
VisIt_VariableData_setDataEx(visit_handle obj, int owner, int dataType,
int ncomps, int ntuples, void *ptr, void(*callback)(void*), void *callbackData)
{
VISIT_DYNAMIC_EXECUTE(VariableData_setDataEx,
int, (visit_handle,int,int,int,int,void*,void(*)(void*),void*),
(obj,owner,dataType,ncomps,ntuples,ptr,callback,callbackData));
}
/************************** Fortran callable routines *************************/
#define F_VISITVARDATAALLOC F77_ID(visitvardataalloc_,visitvardataalloc,VISITVARDATAALLOC)
......
......@@ -59,6 +59,9 @@ int VisIt_VariableData_getDataF(visit_handle obj, int *owner, int *nComps, int *
int VisIt_VariableData_getDataD(visit_handle obj, int *owner, int *nComps, int *nTuples, double **);
int VisIt_VariableData_getDataL(visit_handle obj, int *owner, int *nComps, int *nTuples, long **);
int VisIt_VariableData_setData(visit_handle, int, int, int, int, void *);
int VisIt_VariableData_setDataEx(visit_handle, int, int, int, int, void *, void(*)(void*), void *);
#ifdef __cplusplus
}
#endif
......
......@@ -73,6 +73,7 @@ ENDIF(VISIT_STATIC)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${VISIT_COMMON_INCLUDES}
${VTK_INCLUDE_DIRS}
${VISIT_SOURCE_DIR}/avt/DBAtts/MetaData
${VISIT_SOURCE_DIR}/avt/DBAtts/SIL
${VISIT_SOURCE_DIR}/avt/DataBinning
......
......@@ -307,15 +307,25 @@ void
simv2_debug_logs(int level, const char *msg)
{
if(level == 1)
{
debug1 << msg;
}
else if(level == 2)
{
debug2 << msg;
}
else if(level == 3)
{
debug3 << msg;
}
else if(level == 4)
{
debug4 << msg;
}
else if(level == 5)
{
debug5 << msg;
}
}
int
......@@ -694,7 +704,7 @@ SetAttributeSubjectValues(AttributeSubject *atts,
}
int
simv2_set_plot_options(void *e, int plotID, const char *fieldName,
simv2_set_plot_options(void * /*e*/, int plotID, const char *fieldName,
int fieldType, void *fieldVal, int fieldLen)
{
int status = VISIT_ERROR;
......@@ -715,7 +725,7 @@ simv2_set_plot_options(void *e, int plotID, const char *fieldName,
}
int
simv2_set_operator_options(void *e, int plotID, int operatorID, const char *fieldName,
simv2_set_operator_options(void * /*e*/, int plotID, int operatorID, const char *fieldName,
int fieldType, void *fieldVal, int fieldLen)
{
int status = VISIT_ERROR;
......@@ -724,7 +734,7 @@ simv2_set_operator_options(void *e, int plotID, int operatorID, const char *fiel
std::map<int, PlotInformation>::iterator it = GetPlotInformation()->find(plotID);
if(it != GetPlotInformation()->end() && fieldVal != NULL)
{
if(operatorID >= 0 && operatorID < it->second.operators.size())
if(operatorID >= 0 && operatorID < static_cast<int>(it->second.operators.size()))
{
status = SetAttributeSubjectValues(it->second.operators[operatorID].atts,
std::string(fieldName), fieldType, fieldVal, fieldLen);
......
......@@ -115,7 +115,7 @@ SIMV2_API int simv2_invoke_WriteVariable(const char *, const char *, int, visit_
#define VISIT_CURVE_DATA 30
#define VISIT_MATERIAL_DATA 40
#define VISIT_SPECIES_DATA 50
#define VISIT_SPECIES_DATA 50
#define VISIT_SIMULATION_METADATA 100
#define VISIT_MESHMETADATA 101
......
#ifndef VISIT_DATA_INTERFACE_RUNTIME_P_H
#define VISIT_DATA_INTERFACE_RUNTIME_P_H
#include <stdlib.h>
#include <cstddef>
#include <VisItInterfaceTypes_V2.h>
/* This file contains prototypes of functions that are used internally
/* This file contains prototypes of functions that are used internally
in the data interface. These functions are never exposed beyond the
runtime.
*/
......
/*****************************************************************************
*
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
* Produced at the Lawrence Livermore National Laboratory
* LLNL-CODE-442911
* All rights reserved.
*
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the disclaimer (as noted below) in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/
#ifndef simV2_DeleteEventObserver_h
#define simV2_DeleteEventObserver_h
#include <vtkCommand.h>
#include <vtkDataArray.h>
// help that invokes callback passed through the simV2
// api when a VTK data array is deleted. This allows us
// to hold a reference to the data while VTK needs it,
// and release that reference when VTK is finished. Note:
// after the callback is invoked, this class un-register's
// itself so one should not explicitly Delete it.
class simV2_DeleteEventObserver : public vtkCommand
{
public:
static simV2_DeleteEventObserver *New()
{ return new simV2_DeleteEventObserver; }
// Install the observer on the DeleteEvent.
void Observe(vtkDataArray *object, void(*callback)(void*), void*callbackData)
{
this->Id = object->AddObserver(vtkCommand::DeleteEvent, this);
this->Callback = callback;
this->CallbackData = callbackData;
}
// invoke the callback, ignore the event, delete the observer
virtual void Execute(vtkObject *object, unsigned long, void *)
{
this->Callback(this->CallbackData);
object->RemoveObserver(this->Id);
this->UnRegister();
}
protected:
simV2_DeleteEventObserver() : Id(0), Callback(NULL), CallbackData(NULL) {}
virtual ~simV2_DeleteEventObserver() {}
unsigned long Id;
void(* Callback)(void*);
void *CallbackData;
private:
void operator=(const simV2_DeleteEventObserver &); // not implemented
simV2_DeleteEventObserver(const simV2_DeleteEventObserver &); // not implemented
};
#endif
......@@ -273,7 +273,7 @@ simv2_MaterialData_addMixedCell(visit_handle h, int cell,
VisItError("An invalid volume fraction array was provided");
return VISIT_ERROR;
}
if(nmats < 1 || nmats > obj->matnos.size())
if(nmats < 1 || nmats > static_cast<int>(obj->matnos.size()))
{
VisItError("An invalid number of materials was provided");
return VISIT_ERROR;
......@@ -426,7 +426,7 @@ simv2_MaterialData_getMaterial(visit_handle h, int i,
{
VisIt_MaterialData *obj = GetObject(h);
int retval = VISIT_ERROR;
if(obj != NULL && i >= 0 && i < obj->matnos.size())
if(obj != NULL && i >= 0 && i < static_cast<int>(obj->matnos.size()))
{
matno = obj->matnos[i];
strncpy(matname, obj->matNames[i].c_str(), maxlen);
......
......@@ -239,7 +239,7 @@ simv2_MaterialMetaData_getMaterialName(visit_handle h, int i, char **val)
}
int retval = VISIT_ERROR;
VisIt_MaterialMetaData *obj = GetObject(h, "simv2_MaterialMetaData_getMaterialName");
if(obj != NULL && i >= 0 && i < obj->materialNames.size())
if(obj != NULL && i >= 0 && i < static_cast<int>(obj->materialNames.size()))
{
*val = (char *)malloc(obj->materialNames[i].size() + 1);
strcpy(*val, obj->materialNames[i].c_str());
......
......@@ -478,7 +478,7 @@ simv2_MeshMetaData_getDomainName(visit_handle h, int i, char **val)
}
int retval = VISIT_ERROR;
VisIt_MeshMetaData *obj = GetObject(h, "simv2_MeshMetaData_getDomainName");
if(obj != NULL && i >= 0 && i < obj->domainNames.size())
if(obj != NULL && i >= 0 && i < static_cast<int>(obj->domainNames.size()))
{
*val = (char *)malloc(obj->domainNames[i].size() + 1);
strcpy(*val, obj->domainNames[i].c_str());
......@@ -638,7 +638,7 @@ simv2_MeshMetaData_getGroupId(visit_handle h, int i, int *val)
{
int retval = VISIT_ERROR;
VisIt_MeshMetaData *obj = GetObject(h, "simv2_MeshMetaData_getGroupId");
if(obj != NULL && i >= 0 && i < obj->groupIds.size())
if(obj != NULL && i >= 0 && i < static_cast<int>(obj->groupIds.size()))
{
*val = obj->groupIds[i];
retval = VISIT_OKAY;
......
......@@ -251,7 +251,7 @@ FUNC2(visit_handle h, int i, visit_handle &val) \
VisIt_SimulationMetaData *obj = GetObject(h, #FUNC2); \
if(obj != NULL) \
{ \
if(i < 0 || i >= obj->VEC.size()) \
if(i < 0 || i >= static_cast<int>(obj->VEC.size())) \
{ \
VisItError("An invalid index was provided"); \
return VISIT_ERROR; \
......
/*****************************************************************************
*
* Copyright (c) 2000 - 2013, Lawrence Livermore National Security, LLC
* Produced at the Lawrence Livermore National Laboratory
* LLNL-CODE-442911
* All rights reserved.
*
* This file is part of VisIt. For details, see https://visit.llnl.gov/. The
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the disclaimer (as noted below) in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of the LLNS/LLNL nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
* LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/
#ifndef simV2_TypeTraits_hxx
#define simV2_TypeTraits_hxx
#include <vtkFloatArray.h>
#include <vtkDoubleArray.h>
#include <vtkIntArray.h>
#include <vtkUnsignedCharArray.h>
#include <vtkLongArray.h>
// template type traits for conversions between VisIt's datatype
// enumerations (eg VISIT_DATATYPE_FLOAT), VTK arrays and enumerations
// (eg vtkFloatArray, VTK_FLOAT), and C++ types (eg. float).
// Given a VisIt C++ type enum, the class provides the following
// typdefs:
// ::cppType -> C++ type (eg float)
// ::vtkType -> a vtkDataArray subclass (eg vtkFloatArray)
// ::vtkEnum -> the VTK C++ type enum (eg VTK_FLOAT)
template<int E> class simV2_TypeTraits {};
#define simV2_TypeTraits_Specialize(visitE, cppT, vtkT, vtkE) \
template<> class simV2_TypeTraits<visitE> \
{ \
public: \
typedef cppT cppType; \
typedef vtkT vtkType; \
enum { vtkEnum = vtkE }; \
};
simV2_TypeTraits_Specialize(VISIT_DATATYPE_FLOAT, float, vtkFloatArray, VTK_FLOAT);
simV2_TypeTraits_Specialize(VISIT_DATATYPE_DOUBLE, double, vtkDoubleArray, VTK_DOUBLE);
simV2_TypeTraits_Specialize(VISIT_DATATYPE_INT, int, vtkIntArray, VTK_INT);
simV2_TypeTraits_Specialize(VISIT_DATATYPE_CHAR, unsigned char, vtkUnsignedCharArray, VTK_UNSIGNED_CHAR);
simV2_TypeTraits_Specialize(VISIT_DATATYPE_LONG, long, vtkLongArray, VTK_LONG);
// The simV2TemplateMacro avoids duplication of long switch statement
// case lists. It enumerates the "case" body for each datatype in
// simV2's API providing "simV2_TT" typedef for each case.
//
// This version of the macro allows the template to take any number of
// arguments. Example usage:
// switch(dataType)
// {
// simV2TemplateMacro(
// myFunc(static_cast<simV2_TT::cppType>(data), arg2));
// }
#define simV2TemplateMacroCase(visitE, call) \
case visitE: { typedef simV2_TypeTraits<visitE> simV2_TT; call; }; break
#define simV2TemplateMacro(call) \
simV2TemplateMacroCase(VISIT_DATATYPE_FLOAT, call); \
simV2TemplateMacroCase(VISIT_DATATYPE_DOUBLE, call); \
simV2TemplateMacroCase(VISIT_DATATYPE_INT, call); \
simV2TemplateMacroCase(VISIT_DATATYPE_CHAR, call); \
simV2TemplateMacroCase(VISIT_DATATYPE_LONG, call);
// The simV2FloatTemplateMacro does the same things as simV2TemplateMacro
// however it only expands the cases for float and double. This addresses
// common situations in numerical computation where integers don't make sense
// and for use with vtkPoints which only suppport float and double.
#define simV2FloatTemplateMacro(call) \
simV2TemplateMacroCase(VISIT_DATATYPE_FLOAT, call); \
simV2TemplateMacroCase(VISIT_DATATYPE_DOUBLE, call);
// verify that the type enum names one of the supported types
inline
bool simV2_ValidDataType(int dataType)
{
if ( (dataType == VISIT_DATATYPE_CHAR)
|| (dataType == VISIT_DATATYPE_INT)
|| (dataType == VISIT_DATATYPE_LONG)
|| (dataType == VISIT_DATATYPE_FLOAT)
|| (dataType == VISIT_DATATYPE_DOUBLE) )
{
return true;
}
return false;
}
// verify that the type enum names one of the supported types
inline
bool simV2_ValidFloatDataType(int dataType)
{
if ( (dataType == VISIT_DATATYPE_FLOAT)
|| (dataType == VISIT_DATATYPE_DOUBLE) )
{
return true;
}
return false;
}
#endif
......@@ -4,6 +4,8 @@
#include "VisItDataInterfaceRuntimeP.h"
#include "simv2_VariableData.h"
#include "simv2_TypeTraits.hxx"
#include <stdio.h>
struct VisIt_VariableData : public VisIt_ObjectBase
{
......@@ -15,29 +17,36 @@ struct VisIt_VariableData : public VisIt_ObjectBase
int nComponents;
int nTuples;
void *data;
void (*callback)(void *);
void *callbackData;
};
VisIt_VariableData::VisIt_VariableData() : VisIt_ObjectBase(VISIT_VARIABLE_DATA)
{
{
owner = VISIT_OWNER_VISIT;
dataType = VISIT_DATATYPE_FLOAT;
nComponents = 1;
nTuples = 0;
data = NULL;
callback = NULL;
callbackData = NULL;
}
VisIt_VariableData::~VisIt_VariableData()
{
if(owner == VISIT_OWNER_VISIT &&
data != NULL)
if ((owner == VISIT_OWNER_VISIT) && (data != NULL))
{
free(data);
}
else
if ((owner == VISIT_OWNER_VISIT_EX) && (callback != NULL))
{
callback(callbackData);
}
}
static VisIt_VariableData *
GetObject(visit_handle h, const char *fname)
GetVariableDataObject(visit_handle h, const char *fname)
{
char tmp[100];
VisIt_VariableData *obj = (VisIt_VariableData *)VisItGetPointer(h);
......@@ -61,9 +70,11 @@ GetObject(visit_handle h, const char *fname)
return obj;
}
/*******************************************************************************
* Public functions, available to C
* Public functions, available to C
******************************************************************************/
int
simv2_VariableData_alloc(visit_handle *h)
{
......@@ -74,7 +85,7 @@ simv2_VariableData_alloc(visit_handle *h)
int
simv2_VariableData_free(visit_handle h)
{
VisIt_VariableData *obj = GetObject(h, "simv2_VariableData_free");
VisIt_VariableData *obj = GetVariableDataObject(h, "simv2_VariableData_free");
int retval = VISIT_ERROR;
if(obj != NULL)
{
......@@ -91,18 +102,15 @@ simv2_VariableData_setData(visit_handle h, int owner, int dataType, int nComps,
{
if(owner != VISIT_OWNER_SIM &&
owner != VISIT_OWNER_VISIT &&
owner != VISIT_OWNER_VISIT_EX &&
owner != VISIT_OWNER_COPY)
{
VisItError("VariableData's owner must be set to VISIT_OWNER_SIM"
", VISIT_SIM_VISIT, or VISIT_OWNER_COPY.");
", VISIT_OWNER_VISIT, VISIT_OWNER_VISIT_EX, or VISIT_OWNER_COPY.");
return VISIT_ERROR;
}
if(dataType != VISIT_DATATYPE_CHAR &&
dataType != VISIT_DATATYPE_INT &&
dataType != VISIT_DATATYPE_FLOAT &&
dataType != VISIT_DATATYPE_DOUBLE &&
dataType != VISIT_DATATYPE_LONG)
if(!simV2_ValidDataType(dataType))
{
VisItError("VariableData's data type must be set to one of: "
"VISIT_DATATYPE_CHAR, VISIT_DATATYPE_INT, VISIT_DATATYPE_FLOAT, "
......@@ -132,53 +140,78 @@ simv2_VariableData_setData(visit_handle h, int owner, int dataType, int nComps,
void *realData = data;
if(owner == VISIT_OWNER_COPY)
{
size_t sz = 1;
if(dataType == VISIT_DATATYPE_CHAR)
sz = sizeof(char);
else if(dataType == VISIT_DATATYPE_INT)
sz = sizeof(int);
else if(dataType == VISIT_DATATYPE_LONG)
sz = sizeof(long);
else if(dataType == VISIT_DATATYPE_FLOAT)
sz = sizeof(float);
else
sz = sizeof(double);
sz *= nComps;
sz *= nTuples;
realData = malloc(sz);
if(realData != NULL)
switch (dataType)
{
memcpy(realData, data, sz);
realOwner = VISIT_OWNER_VISIT;
}
else
{
VisItError("Could not allocate memory to copy data");
return VISIT_ERROR;
simV2TemplateMacro(
size_t sz = nComps*nTuples*sizeof(simV2_TT::cppType);
realData = malloc(sz);
if(realData != NULL)
{
memcpy(realData, data, sz);
realOwner = VISIT_OWNER_VISIT;
}
else
{
VisItError("Could not allocate memory to copy data");
return VISIT_ERROR;
}
);
}
}
int retval = VISIT_ERROR;
VisIt_VariableData *obj = GetObject(h, "simv2_VariableData_setData");
VisIt_VariableData *obj = GetVariableDataObject(h, "simv2_VariableData_setData");
if(obj != NULL)
{
obj->owner = realOwner;
obj->dataType = dataType;
obj->dataType = dataType;
obj->nComponents = nComps;
obj->nTuples = nTuples;
obj->data = realData;
if (owner != VISIT_OWNER_VISIT_EX)
{
obj->callback = NULL;
obj->callbackData = NULL;
}
retval = VISIT_OKAY;
}
return retval;
}
int
simv2_VariableData_setDataEx(visit_handle h, int owner, int dataType,
int nComps, int nTuples, void *data, void (*callback)(void*),
void *callbackData)
{
if (owner == VISIT_OWNER_VISIT_EX)
{
if (callback == NULL)
{
VisItError("VISIT_OWNER_VISIT_EX specified "
"but a callback was not provided.");
return VISIT_ERROR;
}
VisIt_VariableData *obj = GetVariableDataObject(h, "simv2_VariableData_setData");
if(obj == NULL)
{
VisItError("Failed to locate the object from the given handle.");
return VISIT_ERROR;
}
obj->callback = callback;
obj->callbackData = callbackData;
}
return simv2_VariableData_setData(h, owner, dataType, nComps, nTuples, data);
}
int
simv2_VariableData_getData2(visit_handle h, int *owner, int *dataType, int *nComps,
int *nTuples, void **data)
{
int retval = VISIT_ERROR;
VisIt_VariableData *obj = GetObject(h, "simv2_VariableData_getData");
VisIt_VariableData *obj = GetVariableDataObject(h, "simv2_VariableData_getData");
if(obj != NULL)
{
if(obj->data == NULL)
......@@ -207,7 +240,7 @@ simv2_VariableData_getData(visit_handle h, int &owner, int &dataType, int &nComp
int &nTuples, void *&data)
{
int retval = VISIT_ERROR;
VisIt_VariableData *obj = GetObject(h, "simv2_VariableData_getData");
VisIt_VariableData *obj = GetVariableDataObject(h, "simv2_VariableData_getData");
if(obj != NULL)
{
if(obj->data == NULL)
......@@ -227,16 +260,46 @@ simv2_VariableData_getData(visit_handle h, int &owner, int &dataType, int &nComp
return retval;
}
int
simv2_VariableData_getDataEx(visit_handle h, int &owner, int &dataType, int &nComps,
int &nTuples, void *&data, void (*&callback)(void*), void *&callbackData)
{
int retval = VISIT_ERROR;
VisIt_VariableData *obj = GetVariableDataObject(h, "simv2_VariableData_getDataEx");
if(obj != NULL)
{
if(obj->data == NULL)
{
VisItError("The data array does not contain any data");
return VISIT_ERROR;
}
owner = obj->owner;
dataType = obj->dataType;
nComps = obj->nComponents;
nTuples = obj->nTuples;
data = obj->data;
callback = obj->callback;
callbackData = obj->callbackData;