翻译HoudiniEngine官方文档:Sessions

2024-09-06 23:18

本文主要是介绍翻译HoudiniEngine官方文档:Sessions,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

官方文档:《Houdini Engine 3.6: Sessions》

介绍

session的概念是在 Houdini Engine 2.x 中引入的。 在先前版本中,Houdini Engine 的动态链接库,也就是libHAPI,会直接链接到Houdini的核心组件,而宿主程序通常又链接到libHAPI。 这意味着 Houdini Engine 的实现是在宿主进程中运行的。

这一设计有两个主要问题:

  • 因为libHAPI在宿主进程中加载了核心的Houdini库,而这些库又有多个第三方依赖项。因此它们很可能与宿主应用程序自身的依赖项发生冲突
  • 每一个进程只能有一个Houdini场景。

在 Houdini Engine 3.x 中,我们仍支持这种“进程内”的形式——这对于简单的宿主程序可能仍旧是一个不错的选择。然而,我们还提供了一种新的 IPC(inter-process communication:进程间通信) 机制。这样,宿主应用程序可以运行多个session——在它自己的进程中或单独的进程中——以并行的方式或是在其他机器上(如果需要的话)。

每一个这样的session都用 HAPI_Session 来表示,大多数HAPI中的函数都需要它作为参数。

进程外(Out-of-process)

另一方面,如果你想利用 “IPC实现” 的优势,或者说你想以较低的开销轻松地在 “IPC实现” 与 “进程内实现” 做切换,你应该将你的应用链接到libHAPILlibHAPIL代表 Houdini Engine API Loader,它是一个充当 “楔子”(shim) 的库,它可以加载libHAPIlibHARC(我们的IPC客户端实现)、或者甚至是一个用户提供的动态库。

libHAPIL导出在HAPI.h中声明的函数。这些函数中的大多数都被重定向到一个动态链接实现的库(例如libHAPIlibHARC),而其他函数是用于加载库和创建session的特殊函数,并在libHAPIL本身中实现。

如果你将应用链接到libHAPIL,那么你必须在调用任何使用session作为参数的HAPI函数(包括HAPI_Initialize())之前,显式地创建一个session

比如说,HAPI_CreateInProcessSession() 动态加载libHAPI并在其输出参数中返回一个 “进程内session” 的单例。 请注意,在调用此函数之前,不会有任何Houdini库和依赖项在宿主进程中加载。 这可能有助于解决依赖关系问题。

你可以在调用HAPI_CreateInProcessSession()时传入 NULL 表示被创建的 “进程内session” 的单例。

如果你想使用我们的 “基于Thrift的IPC实现”,那么在创建session时,你可以:

  • 使用HAPI_CreateThriftSocketSession()(使用“TCP sockets”作为传输层)
  • 或者HAPI_CreateThriftNamedPipeSession()(在Windows系统上使用“named pipes”,在类Unix系统上使用“domain sockets”)

首次创建Thrift的session时,libHAPIL会加载libHARC,即客户端的动态库,为HAPI调用实现Thrift绑定。

你甚至可以实现自己定义的IPC客户端库,使用HAPI_BindCustomImplementation()将其绑定到HAPI_SessionType枚举中的自定义插槽之一,并使用HAPI_CreateCustomSession()创建基于此实现的session,并将创建session所需的参数作为原始指针传递。

最后,当session的工作结束了之后,可以使用HAPI_CloseSession()将其关闭。 在libHARC实现中,这将关闭客户端与服务器的连接。 如果在客户端的生存期内未使用HAPI_CloseSession()显式地关闭session,则在客户端进程终止时将自动关闭该session

使用“自动关闭”这个选项创建session时,关联的服务器进程将在最后一个session关闭时终止。 请注意,在非Windows系统上,必须在宿主应用程序中处理“SIGCHLD event”,以使服务器进程完全终止并返回 license。

请注意,session可以打开多个,实现的库也可以同时加载多个。

这是个简单的示例,展示了如何启动和连接一个 “进程外session”,以及如何初始化Houdini Engine API。

// HARS(Houdini-Engine API Remote Server)选项
HAPI_ThriftServerOptions serverOptions{ 0 };
serverOptions.autoClose = true;
serverOptions.timeoutMs = 3000.0f;
// 使用"hapi"名字的 Named Pipe 来创建我们的HARS服务器
// 如果你之前已经手动启动了 HARS,则可以忽略这个调用
if (HAPI_RESULT_SUCCESS != HAPI_StartThriftNamedPipeServer(&serverOptions, "hapi", nullptr))return false;
// 创建一个新的 HAPI session,它会使用刚才那个服务器
HAPI_Session session;
if (HAPI_RESULT_SUCCESS != HAPI_CreateThriftNamedPipeSession(&session, "hapi"))return false;
// 初始化 HAPI
HAPI_CookOptions cookOptions = HAPI_CookOptions_Create();
if (HAPI_RESULT_SUCCESS != HAPI_Initialize(&session,           // session:你正在与之交互的 session。如果是 NULL则表示使用默认的 “进程内session”&cookOptions,       // cook options:一个全局的 cook option,后续的cook默认都会用它。//			     每次cook都可以覆盖此设置,但是如果你选择在cook_on_load设置为true的情况下实例化 asset,则将使用这个选项。true,               // use_cooking_thread:是否使用一个不同的线程来cook,这允许异步cook和更大的栈尺寸。-1,                 // cooking_thread_stack_size:设置cook线程的栈的尺寸,单位为 byte。“-1”代表使用 Houdini的默认值。"",                 // houdini_environment_files:一串路径列表(在Windows上以“;”作为分隔符,在Linux和Mac上以“:”作为分隔符)。//							  这些文件后缀为 .env 的文件遵循Houdini用户偏好文件夹中的 houdini.env 文件的格式。//							  它们将会在默认的 houdini.env 文件之后应用,并会覆盖掉进程的环境变量的值//							  你可以使用它来在运行HoudiniEngine时强制为一个更严格的环境。详见:http://www.sidefx.com/docs/houdini/basics/config_envnullptr,            // otl_search_path:OTL 的搜索路径。nullptr,            // dso_search_path:通用的 DSO(自定义插件)的搜索路径。nullptr,            // image_dso_search_path:图像的 DSO(自定义插件)的搜索路径。nullptr     ))      // audio_dso_search_path:音频的 DSO(自定义插件)的搜索路径。
{return false
}

进程内(In-Process)

如果你对使用IPC不感兴趣,只想在进程内运行 Houdini Engine,则可以将宿主应用程序直接链接到libHAPI,并且在成功调用HAPI_Initialize()之前不需要调用任何其他函数。

libHAPI包含 Houdini Engine 功能实际的实现,以及与Houdini核心组件直接进行交互的接口,但不包含IPC机制的实现。

如果是从更早的 HAPI 1.x 代码库中移植,则只需向所有HAPI调用添加HAPI_Session指针参数。 使用“进程内”的方式时,这个额外的session指针参数将被忽略,因此你需要将其设置为 NULL 以获得一致性。

HARS (Houdini-Engine API Remote Server)

在客户端上使用libHARC(基于Thrift的IPC库)时,你需要启动服务器的可执行文件HARS,该文件在Houdini安装目录中。 HARS是具有简单命令行参数的控制台应用程序:

$ HARS -h
Allowed options:-h [ --help ]             显示此帮助信息-s [ --socket-port ] arg  服务器端口(如果使用TCP Socket Session)-n [ --named-pipe ] arg   pipe的名字(如果使用named pipe session)-a [ --auto-close ]       当所有客户端被关闭时,自动关闭服务器-r [ --ready-handle ] arg 服务器准备就绪时将设置的 Win32 Event 的句柄(Windows)服务器准备就绪时将发布的 POSIX named semaphore 的名称(Linux / macOS)(用于服务器自动启动)

HARS直接链接到libHAPI、核心的Houdini库、以及它们的依赖项。 因为基于 Thrift 的 IPC 是跨平台的,所以可以在不同平台上构建并运行主进程(使用libHAPILlibHARC)和服务器进程(HARS)。

你能通过“命令行”或者“管线脚本”以所需的选项来启动一个HARS进程。然后使用相应的session创建函数,在应用程序的C ++代码中建立与服务器的客户端连接。或者,你也可以在创建session之前,方便地使用函数HAPI_StartThriftSocketServer() 或HAPI_StartThriftNamedPipeServer() 从C++代码启动服务器。这些函数都会将程序阻塞,直到服务器发出准备好服务的信号为止。也就是说,一旦这些函数成功地返回了,就说明已经可以安全地创建session了。

请注意,HARS服务器当前仅支持单个客户端连接。 如果服务器已经与一个客户端连接了,那么当第二个客户端尝试连接时,第二个客户端就会阻塞,直到第一个连接关闭。

Houdini Engine Debugger

(译者注:在新版18.5中,此功能已经被 Houdini Engine SessionSync 功能替换)

多线程

使用libHARC基于 Thrift 的 RPC 实现时,一个宿主应用程序进程可以与多个HAPIsession进行交互,每个session都以其各自的Houdini状态代表其自己的HARS进程。 这为使用Houdini Engine的应用程序打开了新的多线程可能性。 当使用来自多个线程的多个session时,libHARC被设计为“线程安全”的。

对每个session的访问都受到互斥锁的保护,因此多线程可以安全地访问一个session。但事实上,仅使用一个session是无法真正实现“并行化”的。 在操作顺序有要求的情况下,客户端代码可能还需要在单个session上执行同步操作。 例如,在处理几何体时,设置几何体属性的顺序并不重要,重要的是HAPI_CommitGeo()需要在设置所有几何体属性之后调用。

另一方面,对于多个session,并行化成为可能,因为它们的Houdini上下文是完全独立的。 以下代码示例说明了如何通过独立的session进行操作,从而在异步任务之间并行地读写每个Tile的体数据。

class testharcSession
{
public:testharcSession(){mySession.type = HAPI_SESSION_MAX;mySession.id = 0;}virtual ~testharcSession(){if (mySession.type != HAPI_SESSION_MAX){HARC_TEST_SUCCESS(HAPI_IsSessionValid(&mySession));HARC_TEST_SUCCESS(HAPI_CloseSession(&mySession));HARC_TEST_ASSERT(HAPI_IsSessionValid(&mySession) == HAPI_RESULT_INVALID_SESSION);}}virtual void open() = 0;const HAPI_Session* get(){return &mySession;}
protected:HAPI_Session mySession;
};
class testharcSimpleAutoSession : public testharcSession
{
public:testharcSimpleAutoSession(const char* session_name_suffix,size_t task_id,const HAPI_ThriftServerOptions& server_options){std::ostringstream pipe_name_os;pipe_name_os << "/tmp/testharc_threading_"<< session_name_suffix << task_id << '_'
#ifdef WIN32<< GetCurrentProcessId();
#else<< getpid();
#endifmyPipeName = pipe_name_os.str();myServerOptions = server_options;myServerOptions.autoClose = true;}virtual ~testharcSimpleAutoSession(){if (mySession.type != HAPI_SESSION_MAX){HARC_TEST_SUCCESS(HAPI_IsInitialized(&mySession));HARC_TEST_SUCCESS(HAPI_Cleanup(&mySession));
#ifndef WIN32::unlink(myPipeName.c_str());
#endif}}virtual void open(){HARC_TEST_SUCCESS(HAPI_StartThriftNamedPipeServer(&myServerOptions, myPipeName.c_str(), nullptr));HARC_TEST_SUCCESS(HAPI_CreateThriftNamedPipeSession(&mySession,myPipeName.c_str()));HAPI_CookOptions cook_options = HAPI_CookOptions_Create();cook_options.splitGeosByGroup = false;HARC_TEST_SUCCESS(HAPI_Initialize(&mySession, &cook_options, true, -1,nullptr, nullptr, nullptr, nullptr, nullptr));}
private:HAPI_ThriftServerOptions    myServerOptions;std::string                 myPipeName;
};
class testharcCopyTileValues
{
public:testharcCopyTileValues(const HAPI_Session* dst_session,const HAPI_Session* src_session,HAPI_NodeId node_id,HAPI_PartId part_id,HAPI_NodeId input_node_id,const HAPI_VolumeTileInfo& tile_info,int tile_value_count): myDstSession(dst_session), mySrcSession(src_session), myNodeId(node_id), myPartId(part_id), myInputNodeId(input_node_id), myTileInfo(tile_info), myTileValueCount(tile_value_count){}void operator()(){// 分配 Tile 数据的 Bufferstd::vector<float> tile_values(static_cast<size_t>(myTileValueCount), -5.8f);// 获得颜色数据HARC_TEST_SUCCESS(HAPI_GetVolumeTileFloatData(mySrcSession,myNodeId, myPartId,-8.8f,&myTileInfo, &tile_values.front(), myTileValueCount));// 设置输入体数据上的颜色数据HARC_TEST_SUCCESS(HAPI_SetVolumeTileFloatData(myDstSession,myInputNodeId,0,&myTileInfo, &tile_values.front(), myTileValueCount));}
private:const HAPI_Session * myDstSession;const HAPI_Session * mySrcSession;HAPI_NodeId myNodeId;HAPI_PartId myPartId;HAPI_NodeId myInputNodeId;HAPI_VolumeTileInfo myTileInfo;int myTileValueCount;
};
void
testharcCopyVolume(std::shared_ptr<testharcSession> src_session,std::shared_ptr<testharcSession> dst_session
)
{src_session->open();// 从文件加载资产库HAPI_AssetLibraryId library_id = -1;HARC_TEST_SUCCESS(HAPI_LoadAssetLibraryFromFile(src_session->get(), "HAPI_Test_Volumes_HoudiniFogColor.otl",false, &library_id));HARC_TEST_ASSERT(library_id >= 0);// 实例化资产HAPI_NodeId node_id = -1;HARC_TEST_SUCCESS(HAPI_CreateNode(src_session->get(), -1, "Object/HAPI_Test_Volumes_HoudiniFogColor",nullptr, true, &node_id));HAPI_GeoInfo geo_info;HARC_TEST_SUCCESS(HAPI_GetDisplayGeoInfo(src_session->get(), node_id, &geo_info));// 获得 part 信息,第二个(也就是说索引号是1)part应该是红色体数据const HAPI_PartId part_id = 1;// 获得 part 信息HAPI_PartInfo part_info;HARC_TEST_SUCCESS(HAPI_GetPartInfo(src_session->get(), geo_info.nodeId, part_id, &part_info));// 获得 volume 信息HAPI_VolumeInfo volume_info;HARC_TEST_SUCCESS(HAPI_GetVolumeInfo(src_session->get(), geo_info.nodeId, part_id, &volume_info));HARC_TEST_ASSERT(volume_info.tupleSize == 1);HARC_TEST_ASSERT(!volume_info.hasTaper);dst_session->open();// 创建输入节点来接收体数据HAPI_NodeId input_node_id = -1;HARC_TEST_SUCCESS(HAPI_CreateInputNode(dst_session->get(), &input_node_id, "Input_Volume"));// 设置 part 信息HARC_TEST_SUCCESS(HAPI_SetPartInfo(dst_session->get(), input_node_id, 0, &part_info));// 设置 volume 信息HARC_TEST_SUCCESS(HAPI_SetVolumeInfo(dst_session->get(), input_node_id, 0, &volume_info));// 获得第一个体数据 TileHAPI_VolumeTileInfo tile_info;HARC_TEST_SUCCESS(HAPI_GetFirstVolumeTile(src_session->get(), geo_info.nodeId, part_id, &tile_info));HARC_TEST_ASSERT(tile_info.isValid);std::vector< std::future< void > > futures;const int tile_value_count =volume_info.tileSize *volume_info.tileSize *volume_info.tileSize *volume_info.tupleSize;while (tile_info.isValid){futures.push_back(std::async(std::launch::async,testharcCopyTileValues(dst_session->get(), src_session->get(),geo_info.nodeId, part_id, input_node_id,tile_info, tile_value_count)));// 获得下一个TileHARC_TEST_SUCCESS(HAPI_GetNextVolumeTile(src_session->get(),geo_info.nodeId, part_id,&tile_info));}for (auto & future : futures)future.get();// 提交体数据输入HARC_TEST_SUCCESS(HAPI_CommitGeo(dst_session->get(), input_node_id));// 对节点进行 cookHARC_TEST_SUCCESS(HAPI_CookNode(dst_session->get(), input_node_id, nullptr));HARC_TEST_ASSERT(testharcVerifyInputVolume_HoudiniVolume(dst_session->get(), input_node_id, 0));
}

最后,用于管理session的函数(session创建函数,HAPI_IsSessionValid()和HAPI_CloseSession())共享一个互斥锁。但是它们不会干扰并发调用的常规HAPI函数(除了HAPI_CloseSession(),它会使session无效,如果随后将其传递给HAPI函数将导致未定义的行为)。

你始终可以安全地调用HAPI_IsSessionValid()来确定session是否有效。

这篇关于翻译HoudiniEngine官方文档:Sessions的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143397

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

论文翻译:ICLR-2024 PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS

PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS https://openreview.net/forum?id=KS8mIvetg2 验证测试集污染在黑盒语言模型中 文章目录 验证测试集污染在黑盒语言模型中摘要1 引言 摘要 大型语言模型是在大量互联网数据上训练的,这引发了人们的担忧和猜测,即它们可能已

Adblock Plus官方规则Easylist China说明与反馈贴(2015.12.15)

-------------------------------特别说明--------------------------------------- 视频广告问题:因Adblock Plus的局限,存在以下现象,优酷、搜狐、17173黑屏并倒数;乐视、爱奇艺播放广告。因为这些视频网站的Flash播放器被植入了检测代码,而Adblock Plus无法修改播放器。 如需同时使用ads

Python脚本:TXT文档行数统计

count = 0 #计数变量file_dirs = input('请输入您要统计的文件根路径:')filename = open(file_dirs,'r') #以只读方式打开文件file_contents = filename.read() #读取文档内容到file_contentsfor file_content in file_contents:

bcolz文档

原文:http://bcolz.blosc.org/en/latest/reference.html First level variables bcolz.__version__'''bcolz包的版本。''' bcolz.dask_here'''是否检测到dask的最低版本。''' bcolz.min_dask_version'''需要dask的最低版本(dask是可选

excel翻译软件有哪些?如何高效提翻译?

你是否曾在面对满屏的英文Excel表格时感到头疼?项目报告、数据分析、财务报表... 当这些重要的信息被语言壁垒阻挡时,效率和理解度都会大打折扣。别担心,只需3分钟,我将带你轻松解锁excel翻译成中文的秘籍。 无论是职场新人还是老手,这一技巧都将是你的得力助手,让你在信息的海洋中畅游无阻。 方法一:使用同声传译王软件 同声传译王是一款专业的翻译软件,它支持多种语言翻译,可以excel

WordPress开发中常用的工具或api文档

http://php.net/ http://httpd.apache.org/ https://wordpress.org/ https://cn.wordpress.org/ https://core.svn.wordpress.org/ zh-cn:开发者文档: https://codex.wordpress.org/zh-cn:%E5%BC%80%E5%8F%91%E8%80%

Temu官方宣导务必将所有的点位材料进行检测-RSL资质检测

关于饰品类产品合规问题宣导: 产品法规RSL要求 RSL测试是根据REACH法规及附录17的要求进行测试。REACH法规是欧洲一项重要的法规,其中包含许多对化学物质进行限制的规定和高度关注物质。 为了确保珠宝首饰的安全性,欧盟REACH法规规定,珠宝首饰上架各大电商平台前必须进行RSLReport(欧盟禁限用化学物质检测报告)资质认证,以确保产品不含对人体有害的化学物质。 RSL-铅,