尽管当ANSYSFluent并行运行时,计算节点可以同时对数据执行计算,但当数据从单个公共文件中读取或写入时,操作必须是连续的。文件必须由能够访问所需文件系统的进程打开、读取或写入。通常情况下,计算节点在没有磁盘空间的专用并行机上运行。这意味着所有数据都必须从主机进程读取和/或写入,因为主机进程总是在具有文件系统访问权限的机器上运行,因为它读取和写入案例和数据文件。这意味着,与消息传递宏中的示例不同,数据只传递给计算节点0进行整理,数据现在必须从所有计算节点传递到计算节点0,然后由计算节点0传递给主机节点,主机节点将数据写入文件。这个过程被称为“编组”( "marshalling")。
以下部分更详细地描述了并行读取和写入文件的过程:
在并行UDF中读取文件之前,要将文件从主机复制到节点,请使用以下函数:
host_to_node_sync_file(const char* filename);这可以处理当前工作目录在主机和节点之间不共享的情况(例如,在ANSYS Fluent UDF中)。对于主机,输入参数文件名是要复制到节点的文件的路径。对于节点,输入参数是复制文件的节点上的目录。成功完成后,host_to_node_sync_file()返回复制的字节数,否则返回-1。
Example
在以下示例中,Windows上的主机进程从其本地目录e:\udfs\test复制文件。bat到远程Linux节点上的/tmp目录。
DEFINE_ON_DEMAND(host_to_node_sync){#if RP_HOST int total_bytes_copied = host_to_node_sync_file("e:\\udfs\\test.dat.h5");#endif#if RP_NODE int total_bytes_copied = host_to_node_sync_file("/tmp"); /* The file /tmp/test.dat.h5 can be opened now */#endif printf("Total number of bytes copied is %d\n", total_bytes_copied);}并行写入文件在以下阶段完成:
由于HOST和NODE进程执行不同的任务,下面的示例看起来很长,并使用了大量编译器指令。然而,如果作为一个练习,你复制了这个例子的三个副本,并在每个副本中删除了HOST或NODE版本中未使用的部分,那么你会发现这实际上是一个非常简单的例程。
Example: Writing Data to a Common File on the Host Process’s File System
/******************************************************************* This function will write pressures and positions for a fluid zone to a file on the host machine ********************************************************************/ #include "udf.h" # define FLUID_ID 2 DEFINE_ON_DEMAND(pressures_to_file) { /* Different variables are needed on different nodes */ #if !RP_HOST Domain *domain=Get_Domain(1); Thread *thread; cell_t c; #else int i; #endif #if !RP_NODE FILE *fp = NULL; char filename[]="press_out.txt"; #endif int size; /* data passing variables */ real *array; int pe; #if !RP_HOST thread=Lookup_Thread(domain,FLUID_ID); #endif #if !RP_NODE if ((fp = fopen(filename, "w"))==NULL) Message("\n Warning: Unable to open %s for writing\n",filename); else Message("\nWriting Pressure to %s...",filename); #endif /* UDF Now does 2 different things depending on NODE or HOST */ #if RP_NODE /* Each Node loads up its data passing array */ size=THREAD_N_ELEMENTS_INT(thread); array = (real *)malloc(size * sizeof(real)); begin_c_loop_int(c,thread) array[c]= C_P(c,thread); end_c_loop_int(c,thread) /* Set pe to destination node */ /* If on node_0 send data to host */ /* Else send to node_0 because */ /* compute nodes connect to node_0 & node_0 to host */ pe = (I_AM_NODE_ZERO_P) ? host : node_zero; // C语言用法 PRF_CSEND_INT(pe, &size, 1, myid); PRF_CSEND_REAL(pe, array, size, myid); free(array);/* free array on nodes after data sent */ /* node_0 now collect data sent by other compute nodes *//* and sends it straight on to the host */ if (I_AM_NODE_ZERO_P) compute_node_loop_not_zero (pe) { PRF_CRECV_INT(pe, &size, 1, pe); array = (real *)malloc(size * sizeof(real)); PRF_CRECV_REAL(pe, array, size, pe); PRF_CSEND_INT(host, &size, 1, myid); PRF_CSEND_REAL(host, array, size, myid); free((char *)array); } #endif /* RP_NODE */ #if RP_HOST compute_node_loop (pe) /* only acts as a counter in this loop */ { /* Receive data sent by each node and write it out to the file */ PRF_CRECV_INT(node_zero, &size, 1, node_zero); array = (real *)malloc(size * sizeof(real)); PRF_CRECV_REAL(node_zero, array, size, node_zero); for (i=0; i<size; i++) fprintf(fp, "%g\n", array[i]); free(array); } #endif /* RP_HOST */ #if !RP_NODE fclose(fp); Message("Done\n"); #endif }UDF可以在ANSYSFluent中编译,并支持OpenCL,以便在lnamd64和win64平台上的通用图形处理单元(GPGPU)上执行。要启用OpenCL支持,应在编译udf之前使用以下文本用户界面(TUI)命令:/define/userdefine/enable-udf on gpu。UDF库与libOpenCL链接。lnamd64和OpenCL也是如此。dll。对于在GPU系统上执行,应正确设置适当的环境变量(lnamd64上的LD_LIBRARY_PATH或win64上的%PATH%),以便libOpenCL.so/OpenCL。dll与UDF库一起加载。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删