Skip to main content
U.S. flag

An official website of the United States government

Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

NML Subdivisions

NML Subdivisions

Introduction

While most NML applications need only a couple of undivided NML buffers for communications a few applications might need a large number of NML buffers if they could not be subdivided. NML subdivisions were aimed at two types of applications.

  • Applications that need to share large amounts of data that can be subdivided into sections that do not need to be syncrhonized which each other.
  • Applications that need to provide a query/reply service where many programs can query the service and get replies unique to their query.

An additional layer of software described in The NML Query/Reply Service builds on NML subdivisions to provide an easier to use interface for applications desiring to create/use a query/reply service. So the remainder of this document will focus on the first type of application.

NML Configuration File Changes

To use subdivisions just add "subdiv=<# of subdivisions>" at the end of the buffer line. You may also need to increase the buffer size since the area allocated for each subdivision will be the buffer size minus some overhead divided by the number of subdivisions. Currently, subdivisions cannot be used with STCP,RPC, subscriptions or broadcast options.

NML API Extensions

The NML API is essentially the same as before except that several alternate functions that end with "_subdivision" and take an additional integer to specify which subdivision should be used. The subdivision number should be between 0 and 1 less than the number of subdivisions established in the configuration file.

Here are the C++ prototypes for these functions:

  int     NML::write_subdivision(int subdiv, NMLmsg  &nml_msg);    int     NML::write_subdivision(int subdiv,NMLmsg  *nml_msg);    int     NML::write_if_read_subdivision(int subdiv,NMLmsg  &nml_msg);    int      NML::write_if_read_subdivision(int subdiv,NMLmsg  *nml_msg);    NMLTYPE  NML::read_subdivision(int subdiv);   NMLTYPE NML:: blocking_read_subdivision(int subdiv, double timeout);    NMLTYPE  NML::peek_subdivision(int subdiv);   NMLmsg * NML::get_address_subdivision(int subdiv); 

For more information on what each function does refer to their non subdivision counterparts in NML Programmers Guide(C++ Version).

One additional function was also added to allow users to determine how many subdivisions are available for a particular buffer. Here is it's C++ prototype.

  int NML::get_total_subdivisions(); 

The Java versions of these functions are not yet available.

Example

The example described in this section consists of a writer that sends out a large array and a reader that is only interested in one particular element of the array.

Here is the configuration file used:

# buffers: # nametypehostsizeneut    RPC# buffer# max_proc [type-spec] #SHMEMhostsizeneut    RPC# buffer# max_proc key  B subdiv_buf1SHMEMlocalhost 200000 0x20001050 1       12 1001 TCP=6001 subdiv=100   # processes: # namebuffer       typehost opsserver timeoutmaster c_num P subdiv_readersubdiv_buf1LOCALlocalhost R0INF 10 P subdiv_writersubdiv_buf1LOCALlocalhost W0INF 01  

Here is the code for the writer.

#include "rcs.hh" #include "nml_ex1.hh"   main() {   NML example_nml(ex_format, "subdiv_buf1", "subdiv_writer", "ex_cfg.nml");   EXAMPLE_MSG example_msg[100];   int count;   while(1)     {       count ++;       for(int i = 0; i < 100; i++) {   example_msg[i].i = i;   example_msg[i].f = etime();   example_msg[i].c = 'a' +count%26;    example_nml.write_subdivision(i,example_msg[i]); }       rcs_print("%d\r",count);       esleep(0.1);     } }  

Here is the C++ code for the reader.

#include "rcs.hh" #include "nml_ex1.hh"  main() { RCS_TIMER timer(0.1); NML example_nml(ex_format, "subdiv_buf1", "subdiv_reader", "ex_cfg.nml"); EXAMPLE_MSG *example_msg_ptr; int quit=0;  while(!quit) { switch(example_nml.read_subdivision(3)) { case -1: rcs_print( "A communications error occurred.\n"); quit = 1; break;  case 0: /* The buffer contains the same message */ /* you read last time. */ break;  case EXAMPLE_MSG_TYPE: example_msg_ptr = (EXAMPLE_MSG *)example_nml.get_address_subdivision(3); rcs_print(" We have a new example message. \n"); rcs_print(" The value of its members are:\n "); rcs_print(" f=%f, c=%c, i=%d\n ",  example_msg_ptr->f, example_msg_ptr->c, example_msg_ptr->i); break; } timer.wait(); } } 

Last Modified: March 17,1999

If you have questions or comments regarding this page or you would like to be notified of changes to the RCS library via email, please contact Will Shackleford at shackle [at] cme.nist.gov (shackle[at]cme[dot]nist[dot]gov)

Created July 11, 2014, Updated January 6, 2017