|
|
|
`PairLJCharmmCoulLong::compute` defines an union type `union_int_float_t` in order to be able with operate with the bits of a 32bit floating point number `rsq` as if it was a 32-bit integer.
|
|
|
|
Since the `union` construct cannot be used with RISC-V intrinsic data types, an inline assembler block with a `vmv.v.v` instruction was used instead.
|
|
|
|
the code snippet shows how the data can be successfully moved from a floating point data type to an integer data type.
|
|
|
|
|
|
|
|
```c++
|
|
|
|
__epi_1xf64 vecrsq;
|
|
|
|
__epi_1xi64 vecitable;
|
|
|
|
// vecitable <- vecrsq
|
|
|
|
__asm__ (
|
|
|
|
"nop\n\t"
|
|
|
|
"vmv.v.v %0, %1\n\t"
|
|
|
|
: "=vr" (vecitable)
|
|
|
|
: "vr" (vecrsq)
|
|
|
|
);
|
|
|
|
```
|
|
|
|
|
|
|
|
The downside of this `vmv.v.v`method is that it adds a redundant instruction, since is not actually needed to move data from a register to another, it should be enough just to interpret it as another type.
|
|
|
|
There is an intrinsic that allows converting between mask and integer vector without performing any operation, but not between integer and floating point, although it follows the same underlying principle (conversion between data types with same SEW).
|
|
|
|
|
|
|
|
After the conversion, then, some bit manipulation is performed on the result.
|
|
|
|
This becomes an issue, since in the code it was performed with 32-bit data types, and we use 64-bit data types.
|
|
|
|
To overcome this, we need to convert the bitmask and the shift value from 32 to 64 bits.
|
|
|
|
It cannot be done statically, since these values are generated in generated in `pair.cpp:init_bitmap` based to the settings specified in the input, so a small extra piece of code is needed.
|
|
|
|
|
|
|
|
Since the extracted bit fields are centered at the start of the mantissa, in order to convert the mask and shift value to 64-bit, it is enough to shift and add `(DBL_MANT_DIG - FLT_MANT_DIG)`, which corresponds to the increase of size of the mantissa when switching from single to double precision.
|
|
|
|
Here, we show the code snippet with the transformation to the mask and shift value and a representation of the bit manipulation performed.
|
|
|
|
|
|
|
|
```
|
|
|
|
ncoulmask64 = ((long) ncoulmask) << (DBL_MANT_DIG - FLT_MANT_DIG);
|
|
|
|
ncoulshiftbits64 = ncoulshiftbits + (DBL_MANT_DIG - FLT_MANT_DIG);
|
|
|
|
```
|
|
|
|
|
|
|
|
![lammps_union_mask](uploads/483b72359d0e41d0b754be1518ff2383/lammps_union_mask.png) |
|
|
|
\ No newline at end of file |