Introducing sequence layout 2 – Foreign (Function) Memory API

Java Certification Exams and ProgrammingExams of Java, Introducing sequence layout, Java Exams Introducing sequence layout 2 – Foreign (Function) Memory API
0 Comments

Putting PathElement and VarHandle togheter

The path elements (layout path) are arguments of the MemoryLayout.varHandle() method which is capable to return a VarHandle that can be used to access a memory segment at the layout located via this layout path. The path is considered rooted in this layout.So, in our simple case, we can obtain a VarHandle for seq as follows:

// VarHandle[varType=double,
// coord=[interface java.lang.foreign.MemorySegment, long]]
VarHandle sphandle = seq.varHandle(
  PathElement.sequenceElement());

Our path layout is just a simple navigation via PathElement.sequenceElement(). The returned VarHandle represents variables of type double and contains a CT of (MemorySegment, long).The MemorySegment represents the memory segment from this sequence layout and the long value represents the index in this memory segment. This means that we can set 10 double values as follows:

try (Arena arena = Arena.openConfined()) {
  MemorySegment segment = arena.allocate(seq);
  for (int i = 0; i < seq.elementCount(); i++) {
    sphandle.set(segment, i, Math.random());
  }
  …

Getting these 10 double values can be done as follows:

  for (int i = 0; i < seq.elementCount(); i++) {
    System.out.printf(“\nx = %.2f”, sphandle.get(segment, i));
  }
}

A VarHandle can be created via arrayElementVarHandle(int… shape) as well. This method creates a VarHandle for accessing a memory segment as a multi-dimensional array (this is known as a strided var handler). The varargs argument, shape, represents the size of each nested array dimension. You can find this example in the bundle code.Next, let’s complicate the things a little bit.

Working with nested sequence layouts

Let’s consider the following sequence layout of 400 bytes (5 * 10 * 8 bytes):

SequenceLayout nestedseq = MemoryLayout.sequenceLayout(5,
  MemoryLayout.sequenceLayout(10, ValueLayout.JAVA_DOUBLE));

So, here we have 5 sequence layouts of 10 ValueLayout.JAVA_DOUBLE each. Navigating to the ValueLayout.JAVA_DOUBLE requires a layout path obtained by chaining two calls of sequenceLayout() as follows:

// VarHandle[varType=double, coord=[interface
// java.lang.foreign.MemorySegment, long, long]]
VarHandle nphandle = nestedseq.varHandle(
  PathElement.sequenceElement(),
  PathElement.sequenceElement());

Beside the memory segment, the VarHandle accepts two long values. The first long corresponds to the outer sequence layout, and the second long corresponds to the inner sequence layout. The number of elements (element count) for the outer sequence is 5, and it can be obtained as follows:

long outer = nestedseq.elementCount();

The element count of the inner sequence is 10, and it can be obtained via the select() method as follows:

long inner = ((SequenceLayout) nestedseq.select(
  PathElement.sequenceElement())).elementCount();

Now, outer fits the first long argument in the coordinate’s types of nphandle, while inner fits the second long argument. So, we can get/set the double values of our sequence as follows:

try (Arena arena = Arena.openConfined()) {
  MemorySegment segment = arena.allocate(nestedseq);
  long outer = nestedseq.elementCount();          
  long inner = ((SequenceLayout) nestedseq.select(
    PathElement.sequenceElement())).elementCount();
  for (int i = 0; i < outer; i++) {
    for (int j = 0; j < inner; j++) {
      nphandle.set(segment, i, j, Math.random());
    }
  }
  for (int i = 0; i < outer; i++) {
    System.out.print(“\n—–” + i + “—–“);
    for (int j = 0; j < inner; j++) {
      System.out.printf(“\nx = %.2f”,
        nphandle.get(segment, i, j));
    }
  }
}

In the bundled code, you can see an example relying on ValueLayout.JAVA_DOUBLE.arrayElementVarHandle(5, 10) as well.


Leave a Reply

Your email address will not be published. Required fields are marked *