Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
fi_atomic(3)		       Libfabric v1.15.1		  fi_atomic(3)

NAME
       fi_atomic - Remote atomic functions

       fi_atomic / fi_atomicv /	fi_atomicmsg / fi_inject_atomic
	      Initiates	an atomic operation to remote memory

       fi_fetch_atomic / fi_fetch_atomicv / fi_fetch_atomicmsg
	      Initiates	 an  atomic operation to remote	memory,	retrieving the
	      initial value.

       fi_compare_atomic / fi_compare_atomicv /	fi_compare_atomicmsg
	      Initiates	an atomic compare-operation to remote memory, retriev-
	      ing the initial value.

       fi_atomicvalid  /  fi_fetch_atomicvalid	/   fi_compare_atomicvalid   /
       fi_query_atomic	:  Indicates  if a provider supports a specific	atomic
       operation

SYNOPSIS
	      #include <rdma/fi_atomic.h>

	      ssize_t fi_atomic(struct fid_ep *ep, const void *buf,
		  size_t count,	void *desc, fi_addr_t dest_addr,
		  uint64_t addr, uint64_t key,
		  enum fi_datatype datatype, enum fi_op	op, void *context);

	      ssize_t fi_atomicv(struct	fid_ep *ep, const struct fi_ioc	*iov,
		  void **desc, size_t count, fi_addr_t dest_addr,
		  uint64_t addr, uint64_t key,
		  enum fi_datatype datatype, enum fi_op	op, void *context);

	      ssize_t fi_atomicmsg(struct fid_ep *ep, const struct fi_msg_atomic *msg,
		  uint64_t flags);

	      ssize_t fi_inject_atomic(struct fid_ep *ep, const	void *buf,
		  size_t count,	fi_addr_t dest_addr,
		  uint64_t addr, uint64_t key,
		  enum fi_datatype datatype, enum fi_op	op);

	      ssize_t fi_fetch_atomic(struct fid_ep *ep, const void *buf,
		  size_t count,	void *desc, void *result, void *result_desc,
		  fi_addr_t dest_addr, uint64_t	addr, uint64_t key,
		  enum fi_datatype datatype, enum fi_op	op, void *context);

	      ssize_t fi_fetch_atomicv(struct fid_ep *ep, const	struct fi_ioc *iov,
		  void **desc, size_t count, struct fi_ioc *resultv,
		  void **result_desc, size_t result_count, fi_addr_t dest_addr,
		  uint64_t addr, uint64_t key, enum fi_datatype	datatype,
		  enum fi_op op, void *context);

	      ssize_t fi_fetch_atomicmsg(struct	fid_ep *ep,
		  const	struct fi_msg_atomic *msg, struct fi_ioc *resultv,
		  void **result_desc, size_t result_count, uint64_t flags);

	      ssize_t fi_compare_atomic(struct fid_ep *ep, const void *buf,
		  size_t count,	void *desc, const void *compare,
		  void *compare_desc, void *result, void *result_desc,
		  fi_addr_t dest_addr, uint64_t	addr, uint64_t key,
		  enum fi_datatype datatype, enum fi_op	op, void *context);

	      size_t fi_compare_atomicv(struct fid_ep *ep, const struct	fi_ioc *iov,
		     void **desc, size_t count,	const struct fi_ioc *comparev,
		     void **compare_desc, size_t compare_count,	struct fi_ioc *resultv,
		     void **result_desc, size_t	result_count, fi_addr_t	dest_addr,
		     uint64_t addr, uint64_t key, enum fi_datatype datatype,
		     enum fi_op	op, void *context);

	      ssize_t fi_compare_atomicmsg(struct fid_ep *ep,
		  const	struct fi_msg_atomic *msg, const struct	fi_ioc *comparev,
		  void **compare_desc, size_t compare_count,
		  struct fi_ioc	*resultv, void **result_desc, size_t result_count,
		  uint64_t flags);

	      int fi_atomicvalid(struct	fid_ep *ep, enum fi_datatype datatype,
		  enum fi_op op, size_t	*count);

	      int fi_fetch_atomicvalid(struct fid_ep *ep, enum fi_datatype datatype,
		  enum fi_op op, size_t	*count);

	      int fi_compare_atomicvalid(struct	fid_ep *ep, enum fi_datatype datatype,
		  enum fi_op op, size_t	*count);

	      int fi_query_atomic(struct fid_domain *domain,
		  enum fi_datatype datatype, enum fi_op	op,
		  struct fi_atomic_attr	*attr, uint64_t	flags);

ARGUMENTS
       ep     Fabric endpoint on which to initiate atomic operation.

       buf    Local data buffer	that specifies first operand of	atomic	opera-
	      tion

       iov / comparev /	resultv
	      Vectored data buffer(s).

       count / compare_count / result_count
	      Count  of	 vectored data entries.	 The number of elements	refer-
	      enced, where each	element	is the indicated datatype.

       addr   Address of remote	memory to access.

       key    Protection key associated	with the remote	memory.

       datatype
	      Datatype associated with atomic operands

       op     Atomic operation to perform

       compare
	      Local compare buffer, containing comparison data.

       result Local data buffer	to store initial value of remote buffer

       desc / compare_desc / result_desc
	      Data descriptor associated with the  local  data	buffer,	 local
	      compare  buffer,	and  local  result  buffer, respectively.  See
	      fi_mr(3).

       dest_addr
	      Destination address for connectionless atomic  operations.   Ig-
	      nored for	connected endpoints.

       msg    Message descriptor for atomic operations

       flags  Additional flags to apply	for the	atomic operation

       context
	      User  specified  pointer	to associate with the operation.  This
	      parameter	is ignored if the operation will not generate  a  suc-
	      cessful  completion, unless an op	flag specifies the context pa-
	      rameter be used for required input.

DESCRIPTION
       Atomic transfers	are used to read and update  data  located  in	remote
       memory regions in an atomic fashion.  Conceptually, they	are similar to
       local  atomic  operations  of  a	similar	nature (e.g. atomic increment,
       compare and swap, etc.).	 Updates to remote data	involve	one of several
       operations on the data, and act on specific types of  data,  as	listed
       below.	As  such, atomic transfers have	knowledge of the format	of the
       data being accessed.  A single atomic function may  operate  across  an
       array of	data applying an atomic	operation to each entry, but the atom-
       icity of	an operation is	limited	to a single datatype or	entry.

   Atomic Data Types
       Atomic  functions  may  operate on one of the following identified data
       types.  A given atomic function may support any	datatype,  subject  to
       provider	implementation constraints.

       FI_INT8
	      Signed 8-bit integer.

       FI_UINT8
	      Unsigned 8-bit integer.

       FI_INT16
	      Signed 16-bit integer.

       FI_UINT16
	      Unsigned 16-bit integer.

       FI_INT32
	      Signed 32-bit integer.

       FI_UINT32
	      Unsigned 32-bit integer.

       FI_INT64
	      Signed 64-bit integer.

       FI_UINT64
	      Unsigned 64-bit integer.

       FI_INT128
	      Signed 128-bit integer.

       FI_UINT128
	      Unsigned 128-bit integer.

       FI_FLOAT
	      A	single-precision floating point	value (IEEE 754).

       FI_DOUBLE
	      A	double-precision floating point	value (IEEE 754).

       FI_FLOAT_COMPLEX
	      An  ordered pair of single-precision floating point values (IEEE
	      754), with the first value representing the real	portion	 of  a
	      complex  number  and  the	second representing the	imaginary por-
	      tion.

       FI_DOUBLE_COMPLEX
	      An ordered pair of double-precision floating point values	 (IEEE
	      754),  with  the	first value representing the real portion of a
	      complex number and the second representing  the  imaginary  por-
	      tion.

       FI_LONG_DOUBLE
	      A	 double-extended  precision  floating  point value (IEEE 754).
	      Note that	the size of a long double and number of	bits used  for
	      precision	 is compiler, platform,	and/or provider	specific.  De-
	      velopers that use	long double should ensure  that	 libfabric  is
	      built  using  a long double format that is compatible with their
	      application, and that format is supported	by the provider.   The
	      mechanism	used for this validation is currently beyond the scope
	      of the libfabric API.

       FI_LONG_DOUBLE_COMPLEX
	      An ordered pair of double-extended precision floating point val-
	      ues  (IEEE 754), with the	first value representing the real por-
	      tion of a	complex	number and the second representing the	imagi-
	      nary portion.

   Atomic Operations
       The following atomic operations are defined.  An	atomic operation often
       acts against a target value in the remote memory	buffer and source val-
       ue provided with	the atomic function.  It may also carry	source data to
       replace	the target value in compare and	swap operations.  A conceptual
       description of each operation is	provided.

       FI_MIN Minimum

	      if (buf[i] < addr[i])
		  addr[i] = buf[i]

       FI_MAX Maximum

	      if (buf[i] > addr[i])
		  addr[i] = buf[i]

       FI_SUM Sum

	      addr[i] =	addr[i]	+ buf[i]

       FI_PROD
	      Product

	      addr[i] =	addr[i]	* buf[i]

       FI_LOR Logical OR

	      addr[i] =	(addr[i] || buf[i])

       FI_LAND
	      Logical AND

	      addr[i] =	(addr[i] && buf[i])

       FI_BOR Bitwise OR

	      addr[i] =	addr[i]	| buf[i]

       FI_BAND
	      Bitwise AND

	      addr[i] =	addr[i]	& buf[i]

       FI_LXOR
	      Logical exclusive-OR (XOR)

	      addr[i] =	((addr[i] && !buf[i]) || (!addr[i] && buf[i]))

       FI_BXOR
	      Bitwise exclusive-OR (XOR)

	      addr[i] =	addr[i]	^ buf[i]

       FI_ATOMIC_READ
	      Read data	atomically

	      result[i]	= addr[i]

       FI_ATOMIC_WRITE
	      Write data atomically

	      addr[i] =	buf[i]

       FI_CSWAP
	      Compare values and if equal swap with data

	      if (compare[i] ==	addr[i])
		  addr[i] = buf[i]

       FI_CSWAP_NE
	      Compare values and if not	equal swap with	data

	      if (compare[i] !=	addr[i])
		  addr[i] = buf[i]

       FI_CSWAP_LE
	      Compare values and if less than or equal swap with data

	      if (compare[i] <=	addr[i])
		  addr[i] = buf[i]

       FI_CSWAP_LT
	      Compare values and if less than swap with	data

	      if (compare[i] < addr[i])
		  addr[i] = buf[i]

       FI_CSWAP_GE
	      Compare values and if greater than or equal swap with data

	      if (compare[i] >=	addr[i])
		  addr[i] = buf[i]

       FI_CSWAP_GT
	      Compare values and if greater than swap with data

	      if (compare[i] > addr[i])
		  addr[i] = buf[i]

       FI_MSWAP
	      Swap masked bits with data

	      addr[i] =	(buf[i]	& compare[i]) |	(addr[i] & ~compare[i])

   Base	Atomic Functions
       The base	atomic functions - fi_atomic, fi_atomicv, fi_atomicmsg	-  are
       used  to	transmit data to a remote node,	where the specified atomic op-
       eration is performed against the	target data.  The  result  of  a  base
       atomic  function	 is stored at the remote memory	region.	 The main dif-
       ference between atomic functions	are the	number and type	of  parameters
       that  they  accept  as input.  Otherwise, they perform the same general
       function.

       The call	fi_atomic transfers the	data contained in  the	user-specified
       data buffer to a	remote node.  For connectionless endpoints, the	desti-
       nation  endpoint	 is specified through the dest_addr parameter.	Unless
       the endpoint has	been configured	differently, the  data	buffer	passed
       into  fi_atomic	must  not  be  touched	by  the	 application until the
       fi_atomic call completes	asynchronously.	 The target buffer of  a  base
       atomic  operation must allow for	remote read an/or write	access,	as ap-
       propriate.

       The fi_atomicv call adds	support	for a scatter-gather list to  fi_atom-
       ic.  The	fi_atomicv transfers the set of	data buffers referenced	by the
       ioc parameter to	the remote node	for processing.

       The  fi_inject_atomic  call  is an optimized version of fi_atomic.  The
       fi_inject_atomic	function behaves as if	the  FI_INJECT	transfer  flag
       were  set,  and	FI_COMPLETION  were  not.  That	is, the	data buffer is
       available for reuse immediately on returning from from  fi_inject_atom-
       ic,  and	 no  completion	 event will be generated for this atomic.  The
       completion event	will be	suppressed even	if the endpoint	has  not  been
       configured  with	FI_SELECTIVE_COMPLETION.  See the flags	discussion be-
       low for more details.  The requested message size that can be used with
       fi_inject_atomic	is limited by inject_size.

       The fi_atomicmsg	call supports atomic functions over both connected and
       connectionless endpoints, with the ability to control the atomic	opera-
       tion per	call through the use  of  flags.   The	fi_atomicmsg  function
       takes a struct fi_msg_atomic as input.

	      struct fi_msg_atomic {
		  const	struct fi_ioc *msg_iov;	/* local scatter-gather	array */
		  void		      **desc;	/* local access	descriptors */
		  size_t	      iov_count;/* # elements in ioc */
		  const	void	      *addr;	/* optional endpoint address */
		  const	struct fi_rma_ioc *rma_iov; /* remote SGL */
		  size_t	      rma_iov_count;/* # elements in remote SGL	*/
		  enum fi_datatype    datatype;	/* operand datatype */
		  enum fi_op	      op;	/* atomic operation */
		  void		      *context;	/* user-defined	context	*/
		  uint64_t	      data;	/* optional data */
	      };

	      struct fi_ioc {
		  void	      *addr;	/* local address */
		  size_t      count;	/* # target operands */
	      };

	      struct fi_rma_ioc	{
		  uint64_t    addr;	/* target address */
		  size_t      count;	/* # target operands */
		  uint64_t    key;	/* access key */
	      };

       The following list of atomic operations are usable with base atomic op-
       erations:  FI_MIN,  FI_MAX,  FI_SUM,  FI_PROD, FI_LOR, FI_LAND, FI_BOR,
       FI_BAND,	FI_LXOR, FI_BXOR, and FI_ATOMIC_WRITE.

   Fetch-Atomic	Functions
       The fetch atomic	functions  -  fi_fetch_atomic,	fi_fetch_atomicv,  and
       fi_fetch	atomicmsg - behave similar to the equivalent base atomic func-
       tion.   The  difference between the fetch and base atomic calls are the
       fetch atomic routines return the	initial	value that was stored  at  the
       target  to  the user.  The initial value	is read	into the user provided
       result buffer.  The target buffer of fetch-atomic  operations  must  be
       enabled for remote read access.

       The  following  list  of	atomic operations are usable with fetch	atomic
       operations: FI_MIN, FI_MAX, FI_SUM, FI_PROD, FI_LOR,  FI_LAND,  FI_BOR,
       FI_BAND,	FI_LXOR, FI_BXOR, FI_ATOMIC_READ, and FI_ATOMIC_WRITE.

       For   FI_ATOMIC_READ   operations,  the	source	buffer	operand	 (e.g.
       fi_fetch_atomic buf parameter) is ignored and may be NULL.  The results
       are written into	the result buffer.

   Compare-Atomic Functions
       The compare atomic functions -  fi_compare_atomic,  fi_compare_atomicv,
       and fi_compare atomicmsg	- are used for operations that require compar-
       ing the target data against a value before performing a swap operation.
       The   compare   atomic	functions   support:   FI_CSWAP,  FI_CSWAP_NE,
       FI_CSWAP_LE, FI_CSWAP_LT, FI_CSWAP_GE, FI_CSWAP_GT, and FI_MSWAP.

   Atomic Valid	Functions
       The atomic valid	functions - fi_atomicvalid, fi_fetch_atomicvalid,  and
       fi_compare_atomicvalid  -indicate  which	 operations the	local provider
       supports.  Needed operations not	supported by the provider must be emu-
       lated by	the application.  Each valid call  corresponds	to  a  set  of
       atomic  functions.  fi_atomicvalid checks whether a provider supports a
       specific	base atomic operation for  a  given  datatype  and  operation.
       fi_fetch_atomicvalid  indicates	if  a  provider	 supports  a  specific
       fetch-atomic operation for a given datatype and operation.  And fi_com-
       pare_atomicvalid	 checks	 if  a	provider  supports  a  specified  com-
       pare-atomic operation for a given datatype and operation.

       If an operation is supported, an	atomic valid call will return 0, along
       with  a count of	atomic data units that a single	function call will op-
       erate on.

   Query Atomic	Attributes
       The fi_query_atomic call	acts as	an  enhanced  atomic  valid  operation
       (see  the atomic	valid function definitions above).  It is provided, in
       part, for future	extensibility.	 The  query  operation	reports	 which
       atomic  operations are supported	by the domain, for suitably configured
       endpoints.

       The behavior of fi_query_atomic is adjusted based on the	flags  parame-
       ter.   If  flags	 is 0, then the	operation reports the supported	atomic
       attributes for base atomic operations, similar  to  fi_atomicvalid  for
       endpoints.  If flags has	the FI_FETCH_ATOMIC bit	set, the operation be-
       haves similar to	fi_fetch_atomicvalid.  Similarly, the flag bit FI_COM-
       PARE_ATOMIC  results  in	 query	acting as fi_compare_atomicvalid.  The
       FI_FETCH_ATOMIC and FI_COMPARE_ATOMIC bits may not both be set.

       If the FI_TAGGED	bit is set, the	provider will indicate if it  supports
       atomic  operations to tagged receive buffers.  The FI_TAGGED bit	may be
       used by itself, or in conjunction with the FI_FETCH_ATOMIC and  FI_COM-
       PARE_ATOMIC flags.

       The output of fi_query_atomic is	struct fi_atomic_attr:

	      struct fi_atomic_attr {
		  size_t count;
		  size_t size;
	      };

       The  count  attribute  field  is	as defined for the atomic valid	calls.
       The size	field indicates	the size in bytes of the atomic	datatype.  The
       size field is useful for	datatypes that may differ in  sizes  based  on
       the platform or compiler, such FI_LONG_DOUBLE.

   Completions
       Completed  atomic  operations  are reported to the initiator of the re-
       quest through an	associated completion queue or counter.	 Any user pro-
       vided context specified with the	request	will be	returned  as  part  of
       any  completion	event written to a CQ.	See fi_cq for completion event
       details.

       Any results returned to the initiator as	part of	 an  atomic  operation
       will  be	 available  prior to a completion event	being generated.  This
       will be true even if the	requested completion semantic provides a weak-
       er guarantee.  That is, atomic fetch operations	have  FI_DELIVERY_COM-
       PLETE semantics.	 Completions generated for other types of atomic oper-
       ations indicate that it is safe to re-use the source data buffers.

       Any  updates to data at the target of an	atomic operation will be visi-
       ble to agents (CPU processes, NICs, and other devices)  on  the	target
       node  prior to one of the following occurring.  If the atomic operation
       generates a completion event or updates a  completion  counter  at  the
       target  endpoint, the results will be available prior to	the completion
       notification.  After processing a completion for	 the  atomic,  if  the
       initiator  submits a transfer between the same endpoints	that generates
       a completion at the target, the results will be available prior to  the
       subsequent  transfer's  event.	Or, if a fenced	data transfer from the
       initiator follows the atomic request, the  results  will	 be  available
       prior to	a completion at	the target for the fenced transfer.

       The correctness of atomic operations on a target	memory region is guar-
       anteed  only  when  performed  by  a single actor for a given window of
       time.  An actor is defined as a single libfabric	domain (identified  by
       the  domain  name, and not an open instance of that domain), a coherent
       CPU complex, or other device (e.g. GPU) capable	of  performing	atomic
       operations on the target	memory.	 The results of	atomic operations per-
       formed  by  multiple actors simultaneously are undefined.  For example,
       issuing CPU based atomic	operations to a	target region concurrently be-
       ing updated by NIC based	atomics	may leave the region's data in an  un-
       known  state.  The results of a first actor's atomic operations must be
       visible to a second actor prior to the second  actor  issuing  its  own
       atomics.

FLAGS
       The  fi_atomicmsg,  fi_fetch_atomicmsg,	and fi_compare_atomicmsg calls
       allow the user to specify flags	which  can  change  the	 default  data
       transfer	 operation.   Flags  specified	with atomic message operations
       override	most flags previously configured  with	the  endpoint,	except
       where  noted  (see fi_control).	The following list of flags are	usable
       with atomic message calls.

       FI_COMPLETION
	      Indicates	that a completion entry	should be  generated  for  the
	      specified	operation.  The	endpoint must be bound to a completion
	      queue with FI_SELECTIVE_COMPLETION that corresponds to the spec-
	      ified operation, or this flag is ignored.

       FI_MORE
	      Indicates	 that the user has additional requests that will imme-
	      diately be posted	after the current call returns.	 Use  of  this
	      flag  may	 improve performance by	enabling the provider to opti-
	      mize its access to the fabric hardware.

       FI_INJECT
	      Indicates	that the control of constant data  buffers  should  be
	      returned to the user immediately after the call returns, even if
	      the  operation is	handled	asynchronously.	 This may require that
	      the underlying provider implementation copy the data into	a  lo-
	      cal  buffer  and	transfer  out  of  that	buffer.	 Constant data
	      buffers refers to	any data buffer	or iovec used  by  the	atomic
	      APIs that	are marked as `const'.	Non-constant or	output buffers
	      are  unaffected by this flag and may be accessed by the provider
	      at anytime until the operation has completed.  This flag can on-
	      ly be used with messages smaller than inject_size.

       FI_FENCE
	      Applies to transmits.  Indicates that the	 requested  operation,
	      also known as the	fenced operation, and any operation posted af-
	      ter the fenced operation will be deferred	until all previous op-
	      erations targeting the same peer endpoint	have completed.	 Oper-
	      ations  posted after the fencing will see	and/or replace the re-
	      sults of any operations initiated	prior to the fenced operation.

       The ordering of operations starting at the posting of the fenced	opera-
       tion (inclusive)	to the posting of a subsequent fenced  operation  (ex-
       clusive)	is controlled by the endpoint's	ordering semantics.

       FI_TAGGED
	      Specifies	 that  the  target of the atomic operation is a	tagged
	      receive buffer instead of	an RMA buffer.	When a	tagged	buffer
	      is  the  target  memory  region, the addr	parameter is used as a
	      0-based byte offset into the tagged buffer, with the key parame-
	      ter specifying the tag.

RETURN VALUE
       Returns 0 on success.  On error,	a negative value corresponding to fab-
       ric errno is returned.  Fabric errno values are defined in  rdma/fi_er-
       rno.h.

ERRORS
       -FI_EAGAIN
	      See fi_msg(3) for	a detailed description of handling FI_EAGAIN.

       -FI_EOPNOTSUPP
	      The  requested  atomic  operation	 is not	supported on this end-
	      point.

       -FI_EMSGSIZE
	      The number of atomic operations in a single request exceeds that
	      supported	by the underlying provider.

NOTES
       Atomic operations operate on an array of	 values	 of  a	specific  data
       type.   Atomicity  is only guaranteed for each data type	operation, not
       across the entire array.	 The following pseudo-code  demonstrates  this
       operation  for  64-bit  unsigned	 atomic	 write.	 ATOMIC_WRITE_U64 is a
       platform	dependent macro	that atomically	writes 8 bytes to  an  aligned
       memory location.

	      fi_atomic(ep, buf, count,	NULL, dest_addr, addr, key,
		    FI_UINT64, FI_ATOMIC_WRITE,	context)
	      {
		  for (i = 1; i	< count; i ++)
		      ATOMIC_WRITE_U64(((uint64_t *) addr)[i],
			       ((uint64_t *) buf)[i]);
	      }

       The number of array elements to operate on is specified through a count
       parameter.  This	must be	between	1 and the maximum returned through the
       relevant	 valid operation, inclusive.  The requested operation and data
       type must also be valid for the given provider.

       The ordering of atomic operations carried as part of different  request
       messages	 is  subject  to the message and data ordering definitions as-
       signed to the transmitting and receiving	endpoints.  Both  message  and
       data  ordering  are required if the results of two atomic operations to
       the same	memory buffers are to reflect the second operation  acting  on
       the  results  of	the first.  See	fi_endpoint(3) for further details and
       message size restrictions.

SEE ALSO
       fi_getinfo(3), fi_endpoint(3), fi_domain(3), fi_cq(3), fi_rma(3)

AUTHORS
       OpenFabrics.

Libfabric Programmer's Manual	  2021-06-10			  fi_atomic(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=fi_fetch_atomicmsg&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help