1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0033634: Data Exchange, Step Import - Multithreading Step processing

- add parallel execution on the level of STEPControl_ActorRead. Sendingsimple shapes for healing in parallel;
- add parameter to turn ON/OFF this behavior read.step.parallel.healing, ON by default;
- add jemalloc allocator;
- add CMake option to chose the allocator, jemalloc by default.
This commit is contained in:
ika 2024-03-08 15:12:34 +00:00
parent 9c355a6123
commit d18c6cc5f1
16 changed files with 406 additions and 259 deletions

View File

@ -15,6 +15,10 @@ macro (OCCT_INCLUDE_CMAKE_FILE BEING_INCLUDED_FILE)
endif()
endmacro()
# set using memory manager option for TKernel
set (USE_MMGR_TYPE "JEMALLOC" CACHE STRING "Select using memory manager tool.")
set_property(CACHE USE_MMGR_TYPE PROPERTY STRINGS "NATIVE" "TBB" "JEMALLOC")
# include variable description
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/vardescr")
@ -728,6 +732,14 @@ else()
OCCT_CHECK_AND_UNSET ("3RDPARTY_FLEX_EXECUTABLE")
endif()
# Jemalloc
if ("${USE_MMGR_TYPE}" STREQUAL "JEMALLOC")
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/jemalloc")
else()
OCCT_CHECK_AND_UNSET_GROUP ("3RDPARTY_JEMALLOC")
OCCT_CHECK_AND_UNSET ("INSTALL_JEMALLOC")
endif()
# qt for inspector and samples
if (BUILD_Inspector OR BUILD_SAMPLES_QT)
# check qt 3rdparty path

143
adm/cmake/jemalloc.cmake Normal file
View File

@ -0,0 +1,143 @@
# JeMalloc
if (NOT DEFINED INSTALL_JEMALLOC)
set (INSTALL_JEMALLOC OFF CACHE BOOL "${INSTALL_INSTALL_JEMALLOC_DESCR}")
endif()
# include occt macros. compiler_bitness, os_with_bit, compiler
OCCT_INCLUDE_CMAKE_FILE ("adm/cmake/occt_macros")
# specify JEMALLOC folder in connection with 3RDPARTY_DIR
if (3RDPARTY_DIR AND EXISTS "${3RDPARTY_DIR}")
if (NOT 3RDPARTY_JEMALLOC_DIR OR NOT EXISTS "${3RDPARTY_JEMALLOC_DIR}")
FIND_PRODUCT_DIR ("${3RDPARTY_DIR}" jemalloc JEMALLOC_DIR_NAME)
if (JEMALLOC_DIR_NAME)
set (3RDPARTY_JEMALLOC_DIR "${3RDPARTY_DIR}/${JEMALLOC_DIR_NAME}" CACHE PATH "The directory containing JEMALLOC" FORCE)
set (3RDPARTY_JEMALLOC_DIR "${3RDPARTY_DIR}/${JEMALLOC_DIR_NAME}")
message(STATUS "Info: JEMALLOC detected in ${3RDPARTY_JEMALLOC_DIR}")
endif()
endif()
else()
endif()
# define required JEMALLOC variables
if (NOT DEFINED 3RDPARTY_JEMALLOC_INCLUDE_DIR)
set (3RDPARTY_JEMALLOC_INCLUDE_DIR "" CACHE PATH "the path of headers directory")
endif()
# check 3RDPARTY_${PRODUCT_NAME}_ paths for consistency with specified 3RDPARTY_${PRODUCT_NAME}_DIR
if (3RDPARTY_JEMALLOC_DIR AND EXISTS "${3RDPARTY_JEMALLOC_DIR}")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_JEMALLOC_DIR 3RDPARTY_JEMALLOC_INCLUDE_DIR PATH "the path to JEMALLOC")
CHECK_PATH_FOR_CONSISTENCY (3RDPARTY_JEMALLOC_DIR 3RDPARTY_JEMALLOC_LIBRARY_DIR FILEPATH "The directory containing JEMALLOC libraries")
endif()
# header
if (NOT 3RDPARTY_JEMALLOC_INCLUDE_DIR OR NOT EXISTS "${3RDPARTY_JEMALLOC_INCLUDE_DIR}")
set (HEADER_NAMES jemalloc.h)
# set 3RDPARTY_JEMALLOC_INCLUDE_DIR as notfound, otherwise find_library can't assign a new value to 3RDPARTY_JEMALLOC_INCLUDE_DIR
set (3RDPARTY_JEMALLOC_INCLUDE_DIR "3RDPARTY_JEMALLOC_INCLUDE_DIR-NOTFOUND" CACHE FILEPATH "the path to header directory" FORCE)
if (3RDPARTY_JEMALLOC_DIR AND EXISTS "${3RDPARTY_JEMALLOC_DIR}")
find_path (3RDPARTY_JEMALLOC_INCLUDE_DIR NAMES ${HEADER_NAMES}
PATHS ${3RDPARTY_JEMALLOC_DIR}
PATH_SUFFIXES include/jemalloc
CMAKE_FIND_ROOT_PATH_BOTH
NO_DEFAULT_PATH)
endif()
endif()
if (3RDPARTY_JEMALLOC_INCLUDE_DIR AND EXISTS "${3RDPARTY_JEMALLOC_INCLUDE_DIR}")
list (APPEND 3RDPARTY_INCLUDE_DIRS "${3RDPARTY_JEMALLOC_INCLUDE_DIR}")
else()
list (APPEND 3RDPARTY_NOT_INCLUDED 3RDPARTY_JEMALLOC_INCLUDE_DIR)
set (3RDPARTY_JEMALLOC_INCLUDE_DIR "" CACHE FILEPATH "the path to jemalloc.h" FORCE)
endif()
# Installing destination path
if (WIN32)
set (JEMALLOC_INSTALL_DESTINATION "${INSTALL_DIR}/${INSTALL_DIR_BIN}")
else()
set (JEMALLOC_INSTALL_DESTINATION "${INSTALL_DIR}/${INSTALL_DIR_LIB}")
endif()
macro (JEMALLOC_LIB_SEARCH MMGR_LIB PREFIX)
if (NOT 3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB})
set (JEMALLOC_PATH_SUFFIXES "lib" "bin")
set (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} "3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}-NOTFOUND")
if (3RDPARTY_JEMALLOC_DIR AND EXISTS "${3RDPARTY_JEMALLOC_DIR}")
find_library (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} NAMES ${MMGR_LIB}
PATHS "${3RDPARTY_JEMALLOC_LIBRARY_DIR}" "${3RDPARTY_JEMALLOC_DIR}"
PATH_SUFFIXES ${JEMALLOC_PATH_SUFFIXES}
CMAKE_FIND_ROOT_PATH_BOTH
NO_DEFAULT_PATH)
else()
find_library (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} NAMES ${MMGR_LIB}
PATH_SUFFIXES ${JEMALLOC_PATH_SUFFIXES}
CMAKE_FIND_ROOT_PATH_BOTH)
endif()
if (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB})
get_filename_component (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} "${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}}" PATH)
set (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} "${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}}")
else()
set (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} "")
endif()
endif()
if (3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB})
list (APPEND 3RDPARTY_LIBRARY_DIRS "${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}}")
set (3RDPARTY_JEMALLOC_LIBRARY_DIR "${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}}" CACHE PATH "The directory containing JEMALLOC libraries" FORCE)
else()
message("Cannot find ${MMGR_LIB} library in jemalloc 3rdparty")
list (APPEND 3RDPARTY_NO_LIBS 3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB})
set (3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} "")
endif()
set (JEMALLOC_IS_STATIC_LIB FALSE)
if (((${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} MATCHES "lib$")) OR ((${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} MATCHES "a$")))
get_filename_component(STATIC_LIB_NAME ${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} NAME)
list(APPEND CSF_MMGR "${STATIC_LIB_NAME}")
set (JEMALLOC_IS_STATIC_LIB TRUE)
endif()
# install instructions
if (INSTALL_JEMALLOC AND NOT JEMALLOC_IS_STATIC_LIB)
OCCT_MAKE_OS_WITH_BITNESS()
OCCT_MAKE_COMPILER_SHORT_NAME()
get_filename_component(3RDPARTY_JEMALLOC_LIBRARY ${3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB}} REALPATH)
if (SINGLE_GENERATOR)
install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
DESTINATION "${INSTALL_DIR}/${INSTALL_DIR_LIB}")
else()
install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
CONFIGURATIONS Debug
DESTINATION "${JEMALLOC_INSTALL_DESTINATION}d")
install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
CONFIGURATIONS Release
DESTINATION "${JEMALLOC_INSTALL_DESTINATION}")
install (FILES "${3RDPARTY_JEMALLOC_LIBRARY}"
CONFIGURATIONS RelWithDebInfo
DESTINATION "${JEMALLOC_INSTALL_DESTINATION}i")
endif()
set (USED_3RDPARTY_JEMALLOC_DIR "")
elseif(NOT JEMALLOC_IS_STATIC_LIB)
# the library directory for using by the executable
set (USED_3RDPARTY_JEMALLOC_DIR ${3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB}})
endif()
unset(3RDPARTY_JEMALLOC_LIBRARY_DIR_${MMGR_LIB} CACHE)
unset(3RDPARTY_JEMALLOC_LIBRARY_${PREFIX}_${MMGR_LIB} CACHE)
endmacro()
# Reset CSF variable
set (CSF_MMGR "")
# find static jemalloc lib
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
if (WIN32)
JEMALLOC_LIB_SEARCH ("jemalloc" "STATIC")
elseif(NOT WIN32)
JEMALLOC_LIB_SEARCH ("jemalloc_pic" "STATIC")
SET(CMAKE_FIND_LIBRARY_SUFFIXES "" "so")
JEMALLOC_LIB_SEARCH ("jemalloc.so.2" "SHARED")
endif()
# find shared jemalloc lib
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".so")
JEMALLOC_LIB_SEARCH ("jemalloc" "SHARED")

View File

@ -11,9 +11,12 @@ set(FLAGS_ALREADY_INCLUDED 1)
# project can be switched later to use Intel Compiler (ICC).
# Enforcing -fp:precise ensures that in such case ICC will use correct
# option instead of its default -fp:fast which is harmful for OCCT.
# Enforcing OMP only for internal test env
if (MSVC)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fp:precise")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp")
endif()
# add SSE2 option for old MSVC compilers (VS 2005 - 2010, 32 bit only)

View File

@ -14,6 +14,7 @@ if /I "%VCVER%" == "@COMPILER@" (
set "TBB_DIR=@3RDPARTY_TBB_DLL_DIR@"
set "VTK_DIR=@3RDPARTY_VTK_DLL_DIR@"
set "FFMPEG_DIR=@3RDPARTY_FFMPEG_DLL_DIR@"
set "JEMALLOC_DIR=@3RDPARTY_JEMALLOC_LIBRARY_DIR@"
set "OPENVR_DIR=@3RDPARTY_OPENVR_DLL_DIRS@"
if not "@3RDPARTY_QT_DIR@" == "" (
@ -40,7 +41,7 @@ if /I "%VCVER%" == "@COMPILER@" (
set "CSF_OCCTTestsPath=@CMAKE_SOURCE_DIR@/tests"
set "CSF_OCCTDocPath=@CMAKE_SOURCE_DIR@/doc"
rem for compatability with external application using CASROOT
rem for compatibility with external application using CASROOT
set "CASROOT=@CMAKE_SOURCE_DIR@"
)
)

View File

@ -12,6 +12,7 @@ if [ "$1" == "@BIN_LETTER@" ]; then
export TBB_DIR="@3RDPARTY_TBB_LIBRARY_DIR@"
export VTK_DIR="@3RDPARTY_VTK_LIBRARY_DIR@"
export FFMPEG_DIR="@3RDPARTY_FFMPEG_LIBRARY_DIR@"
export JEMALLOC_DIR="@3RDPARTY_JEMALLOC_LIBRARY_DIR@"
if [ "x@3RDPARTY_QT_DIR" != "x" ]; then
export QTDIR="@3RDPARTY_QT_DIR@"
@ -29,7 +30,7 @@ if [ "$1" == "@BIN_LETTER@" ]; then
export CSF_OCCTTestsPath="@CMAKE_SOURCE_DIR@/tests"
export CSF_OCCTDocPath="@CMAKE_SOURCE_DIR@/doc"
# for compatability with external application using CASROOT
# for compatibility with external application using CASROOT
export CASROOT="@CMAKE_SOURCE_DIR@"
fi
fi

View File

@ -16,6 +16,7 @@ if /I "%VCVER%" == "@COMPILER@" (
set "TBB_DIR=@USED_3RDPARTY_TBB_DIR@"
set "VTK_DIR=@USED_3RDPARTY_VTK_DIR@"
set "FFMPEG_DIR=@USED_3RDPARTY_FFMPEG_DIR@"
set "JEMALLOC_DIR=@USED_3RDPARTY_JEMALLOC_DIR@"
set "OPENVR_DIR=@USED_3RDPARTY_OPENVR_DIR@"
if not "@USED_3RDPARTY_QT_DIR@" == "" (

View File

@ -12,6 +12,7 @@ if [ "$1" == "@BIN_LETTER@" ]; then
export TBB_DIR="@USED_3RDPARTY_TBB_DIR@"
export VTK_DIR="@USED_3RDPARTY_VTK_DIR@"
export FFMPEG_DIR="@USED_3RDPARTY_FFMPEG_DIR@"
export JEMALLOC_DIR="@USED_3RDPARTY_JEMALLOC_DIR@"
if [ "x@USED_3RDPARTY_QT_DIR@" != "x" ]; then
export QTDIR="@USED_3RDPARTY_QT_DIR@"

View File

@ -74,6 +74,10 @@ if not "%DevEnvDir%" == "" (
for /f "usebackq delims=" %%i in (`vswhere.exe -version "[16.0,16.99]" -latest -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
set "DevEnvDir=%%i\Common7\IDE\"
)
) else if /I "%VCFMT%" == "vc143" (
for /f "usebackq delims=" %%i in (`vswhere.exe -version "[17.0,17.99]" -latest -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
set "DevEnvDir=%%i\Common7\IDE\"
)
) else if /I "%VCFMT%" == "gcc" (
rem MinGW
) else (
@ -107,6 +111,11 @@ if /I "%VCFMT%" == "vc9" (
set "VCVARS=%%i\VC\Auxiliary\Build\vcvarsall.bat"
)
set "VCPlatformToolSet=v142"
) else if /I "%VCFMT%" == "vc143" (
for /f "usebackq delims=" %%i in (`vswhere.exe -version "[17.0,17.99]" -latest -requires Microsoft.VisualStudio.Workload.%VCPROP% -property installationPath`) do (
set "VCVARS=%%i\VC\Auxiliary\Build\vcvarsall.bat"
)
set "VCPlatformToolSet=v142"
) else if /I "%VCFMT%" == "gcc" (
rem MinGW
) else (
@ -115,7 +124,7 @@ if /I "%VCFMT%" == "vc9" (
exit
)
rem ----- For compatability with external application using CASROOT -----
rem ----- For compatibility with external application using CASROOT -----
if ["%CASROOT%"] == [""] set "CASROOT=%SCRIPTROOT%"
rem ----- Define path to 3rdparty products -----
@ -126,11 +135,16 @@ if ["%ARCH%"] == ["64"] set VCARCH=amd64
if /I ["%1"] == ["vc141"] set "VCVER=vc14"
if /I ["%1"] == ["vc142"] set "VCVER=vc14"
if /I ["%1"] == ["vc143"] set "VCVER=vc14"
if exist "%CASROOT%\custom.bat" (
call "%CASROOT%\custom.bat" %VCVER% %ARCH% %CASDEB%
)
if not ["%QTDIR%"] == [""] (
set "PATH=%QTDIR%/bin;%PATH%"
set "QT_PLUGIN_PATH=%QTDIR%/plugins"
)
if not ["%TCL_DIR%"] == [""] set "PATH=%TCL_DIR%;%PATH%"
if not ["%TK_DIR%"] == [""] set "PATH=%TK_DIR%;%PATH%"
if not ["%FREETYPE_DIR%"] == [""] set "PATH=%FREETYPE_DIR%;%PATH%"
@ -140,11 +154,8 @@ if not ["%GLES2_DIR%"] == [""] set "PATH=%GLES2_DIR%;%PATH%"
if not ["%TBB_DIR%"] == [""] set "PATH=%TBB_DIR%;%PATH%"
if not ["%VTK_DIR%"] == [""] set "PATH=%VTK_DIR%;%PATH%"
if not ["%FFMPEG_DIR%"] == [""] set "PATH=%FFMPEG_DIR%;%PATH%"
if not ["%JEMALLOC_DIR%"] == [""] set "PATH=%JEMALLOC_DIR%;%PATH%"
if not ["%OPENVR_DIR%"] == [""] set "PATH=%OPENVR_DIR%;%PATH%"
if not ["%QTDIR%"] == [""] (
set "PATH=%QTDIR%/bin;%PATH%"
set "QT_PLUGIN_PATH=%QTDIR%/plugins"
)
rem ----- Set path to 3rd party and OCCT libraries -----
if not "%CSF_OCCTBinPath%" == "" (

View File

@ -2,7 +2,7 @@
aScriptPath=${BASH_SOURCE%/*}; if [ -d "${aScriptPath}" ]; then cd "$aScriptPath"; fi; aScriptPath="$PWD";
# ----- For compatability with external application using CASROOT -----
# ----- For compatibility with external application using CASROOT -----
if [ "${CASROOT}" == "" ]; then
export CASROOT="${aScriptPath}"
fi
@ -69,6 +69,10 @@ if [ "$FFMPEG_DIR" != "" ]; then
THRDPARTY_PATH="${FFMPEG_DIR}:${THRDPARTY_PATH}"
fi
if [ "$JEMALLOC_DIR" != "" ]; then
THRDPARTY_PATH="${JEMALLOC_DIR}:${THRDPARTY_PATH}"
fi
if [ "$QTDIR" != "" ]; then
THRDPARTY_PATH="${QTDIR}/lib:${THRDPARTY_PATH}"
fi

View File

@ -2,7 +2,7 @@
aScriptPath=${BASH_SOURCE%/*}; if [ -d "${aScriptPath}" ]; then cd "$aScriptPath"; fi; aScriptPath="$PWD";
# ----- For compatability with external application using CASROOT -----
# ----- For compatibility with external application using CASROOT -----
if [ "${CASROOT}" == "" ]; then
export CASROOT="@INSTALL_DIR@"
fi
@ -71,6 +71,10 @@ if [ "$FFMPEG_DIR" != "" ]; then
THRDPARTY_PATH="${FFMPEG_DIR}:${THRDPARTY_PATH}"
fi
if [ "$JEMALLOC_DIR" != "" ]; then
THRDPARTY_PATH="${JEMALLOC_DIR}:${THRDPARTY_PATH}"
fi
if [ "$QTDIR" != "" ]; then
THRDPARTY_PATH="${QTDIR}/lib:${THRDPARTY_PATH}"
fi

View File

@ -17,6 +17,7 @@
//gka,abv 14.04.99 S4136: maintain unit context, precision and maxtolerance values
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepCheck_Shell.hxx>
#include <BRepCheck_Status.hxx>
#include <Geom_Axis2Placement.hxx>
@ -32,6 +33,7 @@
#include <Message_ProgressScope.hxx>
#include <OSD_Timer.hxx>
#include <Precision.hxx>
#include <ShapeProcess_ShapeContext.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <Standard_Transient.hxx>
@ -317,7 +319,10 @@ Handle(Transfer_Binder) STEPControl_ActorRead::Transfer
}
// [END] Get version of preprocessor (to detect I-Deas case) (ssv; 23.11.2010)
Standard_Boolean aTrsfUse = (Interface_Static::IVal("read.step.root.transformation") == 0);
return TransferShape(start, TP, Standard_True, aTrsfUse, theProgress);
auto aResult = TransferShape(start, TP, Standard_True, aTrsfUse, theProgress);
if (Interface_Static::IVal("read.step.parallel.healing") == 0)
PostHealing(TP);
return aResult;
}
@ -1480,15 +1485,20 @@ Handle(TransferBRep_ShapeBinder) STEPControl_ActorRead::TransferEntity
if (found && myShapeBuilder.IsDone()) {
mappedShape = myShapeBuilder.Value();
// Apply ShapeFix (on manifold shapes only. Non-manifold topology is processed separately: ssv; 13.11.2010)
if (isManifold && aHasGeom)
if (isManifold&& aHasGeom)
{
Handle(Standard_Transient) info;
mappedShape =
XSAlgo::AlgoContainer()->ProcessShape( mappedShape, myPrecision, myMaxTol,
"read.step.resource.name",
"read.step.sequence", info,
aPS.Next());
XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
if (Interface_Static::IVal("read.step.parallel.healing") != 0)
{
Handle(Standard_Transient) info;
mappedShape =
XSAlgo::AlgoContainer()->ProcessShape(mappedShape, myPrecision, myMaxTol,
"read.step.resource.name",
"read.step.sequence", info,
aPS.Next());
XSAlgo::AlgoContainer()->MergeTransferInfo(TP, info, nbTPitems);
}
else
myShapesToHeal.Add(mappedShape);
}
}
found = !mappedShape.IsNull();
@ -2039,3 +2049,68 @@ void STEPControl_ActorRead::computeIDEASClosings(const TopoDS_Compound& comp,
shellClosingsMap.Add(shellA, closingShells);
}
}
//=======================================================================
// Method : PostHealing
// Purpose : postprocess shape healing
//=======================================================================
Standard_EXPORT void STEPControl_ActorRead::PostHealing(const Handle(Transfer_TransientProcess)& TP)
{
NCollection_Array1<Handle(ShapeProcess_ShapeContext)> aInfos(1, myShapesToHeal.Size());
NCollection_Array1<TopTools_DataMapOfShapeShape> aOrigToCopyMapArr(1, myShapesToHeal.Size());
NCollection_Array1<TopTools_DataMapOfShapeShape> aCopyToOrigMapArr(1, myShapesToHeal.Size());
#pragma omp parallel for
for (int i = 1; i <= myShapesToHeal.Size(); i++)
{
TopoDS_Shape anOrig = myShapesToHeal.FindKey(i);
BRepBuilderAPI_Copy aCurCopy(anOrig, true, true);
TopoDS_Shape aCopy = aCurCopy.Shape();
// Collect all the modified shapes in Copy() for futher update of binders not to lost attached attributes
for (int aTypeIt = anOrig.ShapeType() + 1; aTypeIt <= TopAbs_VERTEX; aTypeIt++)
{
for (TopExp_Explorer anExp(anOrig, (TopAbs_ShapeEnum)aTypeIt); anExp.More(); anExp.Next())
{
const TopoDS_Shape& aSx = anExp.Current();
const TopoDS_Shape& aModifShape = aCurCopy.ModifiedShape(aSx);
aOrigToCopyMapArr.ChangeValue(i).Bind(aSx, aModifShape);
aCopyToOrigMapArr.ChangeValue(i).Bind(aModifShape, aSx);
}
}
Handle(Standard_Transient) anInfo;
aCopy = XSAlgo::AlgoContainer()->ProcessShape(aCopy, myPrecision, myMaxTol,
"read.step.resource.name",
"read.step.sequence", aInfos[i],
Message_ProgressRange());
*(Handle(TopoDS_TShape)&)anOrig.TShape() = *aCopy.TShape();
}
// Update Shape context for correct attributes attaching
Handle(ShapeProcess_ShapeContext) aFullContext = new ShapeProcess_ShapeContext(TopoDS_Shape(), "", "");
TopTools_DataMapOfShapeShape& aHealedMap = (TopTools_DataMapOfShapeShape&)aFullContext->Map();
// Copy maps to the common binders map
for (int i = 1; i <= aOrigToCopyMapArr.Size(); i++)
{
const auto& aForwMap = aOrigToCopyMapArr.Value(i);
const auto& aRevMap = aCopyToOrigMapArr.Value(i);
Handle(ShapeProcess_ShapeContext) aContext = aInfos.Value(i);
for (TopTools_DataMapOfShapeShape::Iterator aMapIt(aForwMap); aMapIt.More(); aMapIt.Next())
{
aHealedMap.Bind(aMapIt.Key(), aMapIt.Value());
}
for (TopTools_DataMapOfShapeShape::Iterator anIter(aContext->Map()); anIter.More(); anIter.Next())
{
TopoDS_Shape aShape;
if (aRevMap.Find(anIter.Key(), aShape))
{
aHealedMap.Bind(aShape, anIter.Value());
}
}
}
XSAlgo::AlgoContainer()->MergeTransferInfo(TP, aFullContext);
CleanShapesToHeal();
}

View File

@ -28,6 +28,7 @@
#include <TopTools_ListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <Message_ProgressRange.hxx>
#include <NCollection_IndexedMap.hxx>
class StepRepr_Representation;
class Standard_Transient;
@ -98,8 +99,14 @@ public:
//! REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION
Standard_EXPORT Standard_Boolean ComputeSRRWT (const Handle(StepRepr_RepresentationRelationship)& SRR, const Handle(Transfer_TransientProcess)& TP, gp_Trsf& Trsf);
//! Heals the collected during transferring shapes
Standard_EXPORT void PostHealing(const Handle(Transfer_TransientProcess)& TP);
//! Cleans collected for post healing shapes.
inline void CleanShapesToHeal()
{
myShapesToHeal.Clear();
}
DEFINE_STANDARD_RTTIEXT(STEPControl_ActorRead,Transfer_ActorOfTransientProcess)
@ -185,8 +192,7 @@ private:
Standard_Real myPrecision;
Standard_Real myMaxTol;
Handle(StepRepr_Representation) mySRContext;
NCollection_IndexedMap<TopoDS_Shape> myShapesToHeal;
};

View File

@ -217,6 +217,12 @@ STEPControl_Controller::STEPControl_Controller ()
Interface_Static::Init("step", "read.step.root.transformation", '&', "eval OFF");
Interface_Static::SetCVal("read.step.root.transformation", "ON");
Interface_Static::Init("step", "read.step.parallel.healing", 'e', "");
Interface_Static::Init("step", "read.step.parallel.healing", '&', "enum 0");
Interface_Static::Init("step", "read.step.parallel.healing", '&', "eval ON");
Interface_Static::Init("step", "read.step.parallel.healing", '&', "eval OFF");
Interface_Static::SetCVal("read.step.parallel.healing", "ON");
// STEP file encoding for names translation
// Note: the numbers should be consistent with Resource_FormatType enumeration
Interface_Static::Init("step", "read.step.codepage", 'e', "");

View File

@ -1,7 +1,4 @@
// Created on: 2005-03-15
// Created by: Peter KURNEV
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
// Copyright (c) 1999-2023 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@ -14,301 +11,173 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Standard.hxx>
#include <Standard_MMgrOpt.hxx>
#include <Standard_MMgrRaw.hxx>
#include <Standard_MMgrTBBalloc.hxx>
#include <Standard_Assert.hxx>
#include <Standard_OutOfMemory.hxx>
#include <stdlib.h>
#if(defined(_WIN32) || defined(__WIN32__))
#include <windows.h>
#include <malloc.h>
#include <locale.h>
#include <windows.h>
#include <malloc.h>
#include <locale.h>
#endif
#if defined(_MSC_VER) || defined(__ANDROID__) || defined(__QNX__)
#include <malloc.h>
#include <malloc.h>
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
#include <mm_malloc.h>
#include <mm_malloc.h>
#else
extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theSize);
extern "C" int posix_memalign(void** thePtr, size_t theAlign, size_t theSize);
#endif
// There is no support for environment variables in UWP
// OSD_Environment could not be used here because of cyclic dependency
#ifdef OCCT_UWP
#define getenv(x) NULL
#ifdef OCCT_MMGT_OPT_JEMALLOC
#define JEMALLOC_NO_DEMANGLE
#include <jemalloc.h>
#endif // OCCT_MMGT_OPT_JEMALLOC
// paralleling with Intel TBB
#ifdef HAVE_TBB
#include <tbb/scalable_allocator.h>
#else
#ifdef OCCT_MMGT_OPT_TBB
#undef OCCT_MMGT_OPT_TBB
#endif
#define scalable_malloc malloc
#define scalable_calloc calloc
#define scalable_realloc realloc
#define scalable_free free
#endif
#ifndef OCCT_MMGT_OPT_DEFAULT
#define OCCT_MMGT_OPT_DEFAULT 0
#endif
//=======================================================================
//class : Standard_MMgrFactory
//purpose : Container for pointer to memory manager;
// used to construct appropriate memory manager according
// to environment settings, and to ensure destruction upon exit
//=======================================================================
class Standard_MMgrFactory
{
public:
static Standard_MMgrRoot* GetMMgr();
~Standard_MMgrFactory();
private:
Standard_MMgrFactory();
Standard_MMgrFactory (const Standard_MMgrFactory&);
Standard_MMgrFactory& operator= (const Standard_MMgrFactory&);
private:
Standard_MMgrRoot* myFMMgr;
};
//=======================================================================
//function : Standard_MMgrFactory
//purpose : Check environment variables and create appropriate memory manager
//=======================================================================
Standard_MMgrFactory::Standard_MMgrFactory()
: myFMMgr (NULL)
{
/*#if defined(_MSC_VER) && (_MSC_VER > 1400)
// Turn ON thread-safe C locale globally to avoid side effects by setlocale() calls between threads.
// After this call all following _configthreadlocale() will be ignored assuming
// Notice that this is MSVCRT feature - on POSIX systems xlocale API (uselocale instead of setlocale)
// should be used explicitly to ensure thread-safety!
// This is not well documented call because _ENABLE_PER_THREAD_LOCALE_GLOBAL flag is defined but not implemented for some reason.
// -1 will set global locale flag to force _ENABLE_PER_THREAD_LOCALE_GLOBAL + _ENABLE_PER_THREAD_LOCALE_NEW behaviour
// although there NO way to turn it off again and following calls will have no effect (locale will be changed only for current thread).
_configthreadlocale (-1);
#endif*/
// Check basic assumption.
// If assertion happens, then OCCT should be corrected for compatibility with such CPU architecture.
Standard_STATIC_ASSERT(sizeof(Standard_Utf8Char) == 1);
Standard_STATIC_ASSERT(sizeof(short) == 2);
Standard_STATIC_ASSERT(sizeof(Standard_Utf16Char) == 2);
Standard_STATIC_ASSERT(sizeof(Standard_Utf32Char) == 4);
#ifdef _WIN32
Standard_STATIC_ASSERT(sizeof(Standard_WideChar) == sizeof(Standard_Utf16Char));
#endif
char* aVar;
aVar = getenv ("MMGT_OPT");
Standard_Integer anAllocId = (aVar ? atoi (aVar): OCCT_MMGT_OPT_DEFAULT);
#if defined(HAVE_TBB) && defined(_M_IX86)
if (anAllocId == 2)
{
// CR25396: Check if SSE2 instructions are supported on 32-bit x86 processor on Windows platform,
// if not then use MMgrRaw instead of MMgrTBBalloc.
// It is to avoid runtime crash when running on a CPU
// that supports SSE but does not support SSE2 (some modifications of AMD Sempron).
static const DWORD _SSE2_FEATURE_BIT(0x04000000);
DWORD volatile dwFeature;
_asm
{
push eax
push ebx
push ecx
push edx
// get the CPU feature bits
mov eax, 1
cpuid
mov dwFeature, edx
pop edx
pop ecx
pop ebx
pop eax
}
if ((dwFeature & _SSE2_FEATURE_BIT) == 0)
anAllocId = 0;
}
#endif
aVar = getenv ("MMGT_CLEAR");
Standard_Boolean toClear = (aVar ? (atoi (aVar) != 0) : Standard_True);
// on Windows (actual for XP and 2000) activate low fragmentation heap
// for CRT heap in order to get best performance.
// Environment variable MMGT_LFH can be used to switch off this action (if set to 0)
#if defined(_MSC_VER)
aVar = getenv ("MMGT_LFH");
if ( aVar == NULL || atoi (aVar) != 0 )
{
ULONG aHeapInfo = 2;
HANDLE aCRTHeap = (HANDLE)_get_heap_handle();
HeapSetInformation (aCRTHeap, HeapCompatibilityInformation, &aHeapInfo, sizeof(aHeapInfo));
}
#endif
switch (anAllocId)
{
case 1: // OCCT optimized memory allocator
{
aVar = getenv ("MMGT_MMAP");
Standard_Boolean bMMap = (aVar ? (atoi (aVar) != 0) : Standard_True);
aVar = getenv ("MMGT_CELLSIZE");
Standard_Integer aCellSize = (aVar ? atoi (aVar) : 200);
aVar = getenv ("MMGT_NBPAGES");
Standard_Integer aNbPages = (aVar ? atoi (aVar) : 1000);
aVar = getenv ("MMGT_THRESHOLD");
Standard_Integer aThreshold = (aVar ? atoi (aVar) : 40000);
myFMMgr = new Standard_MMgrOpt (toClear, bMMap, aCellSize, aNbPages, aThreshold);
break;
}
case 2: // TBB memory allocator
myFMMgr = new Standard_MMgrTBBalloc (toClear);
break;
case 0:
default: // system default memory allocator
myFMMgr = new Standard_MMgrRaw (toClear);
}
}
//=======================================================================
//function : ~Standard_MMgrFactory
//purpose :
//=======================================================================
Standard_MMgrFactory::~Standard_MMgrFactory()
{
if ( myFMMgr )
myFMMgr->Purge(Standard_True);
}
//=======================================================================
// function: GetMMgr
//
// This static function has a purpose to wrap static holder for memory
// manager instance.
//
// Wrapping holder inside a function is needed to ensure that it will
// be initialized not later than the first call to memory manager (that
// would be impossible to guarantee if holder was static variable on
// global or file scope, because memory manager may be called from
// constructors of other static objects).
//
// Note that at the same time we could not guarantee that the holder
// object is destroyed after last call to memory manager, since that
// last call may be from static Handle() object which has been initialized
// dynamically during program execution rather than in its constructor.
//
// Therefore holder currently does not call destructor of the memory manager
// but only its method Purge() with Standard_True.
//
// To free the memory completely, we probably could use compiler-specific
// pragmas (such as '#pragma fini' on SUN Solaris and '#pragma init_seg' on
// WNT MSVC++) to put destructing function in code segment that is called
// after destructors of other (even static) objects. However, this is not
// done by the moment since it is compiler-dependent and there is no guarantee
// thatsome other object calling memory manager is not placed also in that segment...
//
// Note that C runtime function atexit() could not help in this problem
// since its behaviour is the same as for destructors of static objects
// (see ISO 14882:1998 "Programming languages -- C++" 3.6.3)
//
// The correct approach to deal with the problem would be to have memory manager
// to properly control its memory allocation and caching free blocks so
// as to release all memory as soon as it is returned to it, and probably
// even delete itself if all memory it manages has been released and
// last call to method Purge() was with True.
//
// Note that one possible method to control memory allocations could
// be counting calls to Allocate() and Free()...
//
//=======================================================================
Standard_MMgrRoot* Standard_MMgrFactory::GetMMgr()
{
static Standard_MMgrFactory aFactory;
return aFactory.myFMMgr;
}
// Available macros definition
// - OCCT_MMGT_OPT_TBB, using tbb::scalable_allocator
// - OCCT_MMGT_OPT_NATIVE, using native calloc, free
// - OCCT_MMGT_OPT_JEMALLOC, using external jecalloc, jefree
//=======================================================================
//function : Allocate
//purpose :
//purpose :
//=======================================================================
Standard_Address Standard::Allocate(const Standard_Size size)
Standard_Address Standard::Allocate(const Standard_Size theSize)
{
return Standard_MMgrFactory::GetMMgr()->Allocate(size);
#if defined OCCT_MMGT_OPT_JEMALLOC
Standard_Address aPtr = je_calloc(theSize, sizeof(char));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
#elif defined OCCT_MMGT_OPT_TBB
Standard_Address aPtr = scalable_calloc(theSize, sizeof(char));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
#else
Standard_Address aPtr = calloc(theSize, sizeof(char));
if (!aPtr)
throw Standard_OutOfMemory("Standard_MMgrRaw::Allocate(): malloc failed");
return aPtr;
#endif
}
//=======================================================================
//function : Free
//purpose :
//purpose :
//=======================================================================
void Standard::Free (Standard_Address theStorage)
void Standard::Free(Standard_Address theStorage)
{
Standard_MMgrFactory::GetMMgr()->Free(theStorage);
#if defined OCCT_MMGT_OPT_JEMALLOC
je_free(theStorage);
#elif defined OCCT_MMGT_OPT_TBB
scalable_free(theStorage);
#else
free(theStorage);
#endif
}
//=======================================================================
//function : Reallocate
//purpose :
//purpose :
//=======================================================================
Standard_Address Standard::Reallocate (Standard_Address theStorage,
const Standard_Size theSize)
Standard_Address Standard::Reallocate(Standard_Address theStorage,
const Standard_Size theSize)
{
return Standard_MMgrFactory::GetMMgr()->Reallocate (theStorage, theSize);
// Note that it is not possible to ensure that additional memory
// allocated by realloc will be cleared (so as to satisfy myClear mode);
// in order to do that we would need using memset..
#if defined OCCT_MMGT_OPT_JEMALLOC
Standard_Address aNewStorage = (Standard_Address)je_realloc(theStorage, theSize);
if (!aNewStorage)
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
return aNewStorage;
#elif defined OCCT_MMGT_OPT_TBB
Standard_Address aNewStorage = (Standard_Address)scalable_realloc(theStorage, theSize);
if (!aNewStorage)
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
return aNewStorage;
#else
Standard_Address aNewStorage = (Standard_Address)realloc(theStorage, theSize);
if (!aNewStorage)
throw Standard_OutOfMemory("Standard_MMgrRaw::Reallocate(): realloc failed");
return aNewStorage;
#endif
}
//=======================================================================
//function : Purge
//purpose :
//purpose :
//=======================================================================
Standard_Integer Standard::Purge()
{
return Standard_MMgrFactory::GetMMgr()->Purge();
return true;
}
//=======================================================================
//function : AllocateAligned
//purpose :
//=======================================================================
Standard_Address Standard::AllocateAligned (const Standard_Size theSize,
const Standard_Size theAlign)
Standard_Address Standard::AllocateAligned(const Standard_Size theSize,
const Standard_Size theAlign)
{
#ifdef OCCT_MMGT_OPT_JEMALLOC
return je_aligned_alloc(theAlign, theSize);
#elif defined OCCT_MMGT_OPT_TBB
return scalable_aligned_malloc(theSize, theAlign);
#else
#if defined(_MSC_VER)
return _aligned_malloc (theSize, theAlign);
return _aligned_malloc(theSize, theAlign);
#elif defined(__ANDROID__) || defined(__QNX__)
return memalign (theAlign, theSize);
return memalign(theAlign, theSize);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
return _mm_malloc (theSize, theAlign);
return _mm_malloc(theSize, theAlign);
#else
void* aPtr;
if (posix_memalign (&aPtr, theAlign, theSize))
if (posix_memalign(&aPtr, theAlign, theSize))
{
return NULL;
}
return aPtr;
#endif
#endif
}
//=======================================================================
//function : FreeAligned
//purpose :
//=======================================================================
void Standard::FreeAligned (Standard_Address thePtrAligned)
void Standard::FreeAligned(Standard_Address thePtrAligned)
{
#if defined(_MSC_VER)
_aligned_free (thePtrAligned);
#elif defined(__ANDROID__) || defined(__QNX__)
free (thePtrAligned);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
_mm_free (thePtrAligned);
#ifdef OCCT_MMGT_OPT_JEMALLOC
return je_free(thePtrAligned);
#elif defined OCCT_MMGT_OPT_TBB
return scalable_aligned_free(thePtrAligned);
#else
free (thePtrAligned);
#if defined(_MSC_VER)
_aligned_free(thePtrAligned);
#elif defined(__ANDROID__) || defined(__QNX__)
free(thePtrAligned);
#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && (defined(__i386) || defined(__x86_64)))
_mm_free(thePtrAligned);
#else
free(thePtrAligned);
#endif
#endif
}

View File

@ -1,3 +1,12 @@
project(TKernel)
OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)
# Set desired Memory Manager
if ("${USE_MMGR_TYPE}" STREQUAL "TBB")
target_compile_definitions("TKernel" PRIVATE "OCCT_MMGT_OPT_TBB")
elseif ("${USE_MMGR_TYPE}" STREQUAL "JEMALLOC")
target_compile_definitions("TKernel" PRIVATE "OCCT_MMGT_OPT_JEMALLOC")
else ()
message (STATUS "Info: Used native memory manager")
endif()

View File

@ -7,3 +7,4 @@ CSF_dl
CSF_wsock32
CSF_psapi
CSF_androidlog
CSF_MMGR