text:
\section{Introduction}

One-dimensional reaction-diffusion models have received interest over the past decades. In non-equilibrium statistical mechanics these include directed percolation (DP), pair contact process with diffusion (PCPD) and triple contact process with diffusion (TCPD). The interest in these models is mostly whether we can classify the models into one, or more universality classes. Grassberger \cite{grass} and Janssen \cite{janssen} conjectured  that all systems with a single order parameter and a single absorbing state will belong to the universality class of the Directed Percolation model. The order parameter of the reaction-diffusion models considered here is simply the density $\rho$ of the system.

Monte Carlo simulations are very useful in this area of research, because the critical behaviour of these simple models is not understood very well theoretically. The Monte Carlo approach was extensively used on the PCPD model, with varying degrees of success. As shown in \cite{ref:hinrichsen}, there are strong finite-time corrections. Thus, both long time-series and good statistics are mandatory for a proper analysis of the critical behaviour of the system. Acquiring sufficient amounts of data is a very time consuming effort. Thus, we used the parallel processing power of the GPU and clever processing techniques to achieve this in Ref. \cite{schram_pcpd}. This paper will concentrate on the implementation and benchmarks of this algorithm.

This paper uses the PCPD model as an example model that can be simulated using the described algorithm. It is very easy to expand the algorithm to other related models, such as the DP, TCPD and QCDP (Quadruplet Contact Process with Diffusion) models. In fact, the algorithm has already been applied to the TCPD and QCPD models, and analysis of these models will hopefully be published in the near future.

The graphics processing unit (GPU) has been utilized in the last decade for the purpose of gathering high quality data in computational physics: \cite{ref:preis09} (Ising model), \cite{ref:anderson08} (Molecular dynamics) and \cite{nedelcu11} (bond fluctuation model). This paper combines GPU programming with a clever programming technique called multispin programming, that originates from general purpose CPU programming. It has been used for the PCPD problem in Ref. \cite{small2008}. A more thorough explanation of this technique is found in \cite{book_bar}. The relevant parts for our purposes are explained in this paper.

\section{Pair contact process with diffusion}

The PCPD model is a 1+1 dimensional problem from non-equilibrium statistical mechanics. In this model, particles on a lattice can interact in two ways when they are adjacent to each other: both particles can annihilate, or a new particle can be produced adjacent to either particle. Additionally, single particles can diffuse on the lattice. More formally, the reactions are described by the following notation, where A denotes a particle and 0 denotes an empty site on the lattice:

\begin{eqnarray}
\begin{array}{ccc}
\left\{
\begin{array}{ccc}
AA0 & \rightarrow & AAA \\
0AA & \rightarrow & AAA
\end{array} \right.
&{\rm each\,\,with\,\, rate}&
\frac{(1-p)(1-d)} 2 \label{2Ato3A} \\
AA~ \rightarrow ~ 00
&{\rm with \,\,rate}& p\,(1-d) \label{2Ato0}\\
A0  \leftrightarrow  0A &{\rm with \,\,rate}&  d \label{A0to0A}
\end{array}
\label{eq:rates}
\end{eqnarray}

There exist three regimes of the system. A schematic overview is shown in figure \ref{fig:phase}. For a low annihilation rate $p<p_c$, the system will maintain a constant density with very high probability. This is called the active phase. On the other hand, in the case of a high annihilation rate $p>p_c$, the particles in the system will annihilate quickly, and the system is in the inactive phase. On the boundary at the critical annihilation rate $p=p_c$, length and time scales are expected to diverge in a power law fashion, similar to equilibrium phase transitions. The actual value for $p_c$ depends on the diffusion coefficient $d$. For $p$ values far from the critical value $p_c$, the behaviour of the system is well described by mean-field theory. Thus, our interest lies in determining the critical behaviour at or close to $p_c$.

\begin{figure}\centering
\includegraphics[width=10cm]{pics/phase.eps}
\caption{The density of the system as a function of time for the PCPD model, with three different $p$ values: one in the active phase, one close to critical, and one in the inactive phase.}
\label{fig:phase}
\end{figure}

A sequential Monte Carlo algorithm of the PCPD model is shown in algorithm \ref{alg:seq}. It is not optimized for speed, because for instance the number of calls to the random number generator (RNG) can be reduced to only one call. The reason for writing the algorithm this way is that it compares more easily to the GPU algorithm.

\begin{algorithm}[tb]
\caption{Sequential PCPD algorithm}
\begin{algorithmic}[1]\label{alg:seq}

	\STATE \textbf{Input: } configuration $q$ at time $t$.
	\STATE \textbf{Output: } configuration $q$ at time $t+1/L$.

	\medskip
	\STATE \textbf{PCPD\_step\_seq}($q$):
	\STATE \COMMENT{pick a site $i$ on the lattice}
	\STATE $i := \lfloor L\cdot RNG() \rfloor$ \COMMENT{RNG is uniform in $[0,1)$}
	\STATE $r_1 := RNG()$, $r_2 := RNG()$, $r_3 := RNG()$
	\medskip
	\IF{$r_1<d$}
		\STATE Swap($q_i$, $q_{i+1}$) \COMMENT{Diffusion}
	\ELSIF{ $q_i=1$ and $q_{i+1}=1$}
		\IF{$r_2<p$}
			\STATE $q_i := 0,$ $q_{i+1} := 0$ \COMMENT{Annihilation}
		\ELSE
			\IF{$r_3<1/2$}
				\STATE $q_{i-1} := 1$ \COMMENT{Fission low}
			\ELSE
				\STATE $q_{i+2} := 1$ \COMMENT{Fission high}
			\ENDIF
		\ENDIF
	\ENDIF

\end{algorithmic}
\end{algorithm}

\section{GPU programming}

Some algorithms are more easily ported to a GPU architecture than others. It is important to understand the strengths of the GPU to see whether it is worth the effort. First we will give the conditions under which a GPU program can thrive. Our implementation uses the OpenCL \cite{opencl} framework for parallel computing. Therefore, OpenCL terminology will be used to describe the basics of GPU architecture. The difference between the two GPU architectures of the main GPU manufacturers AMD and NVIDIA is far smaller than difference between a CPU and a GPU. For our purpose the difference is small enough, that it does not need a different implementation. Technical specifications of the GPU architectures can be found in \cite{nvidia} (NVIDIA) and \cite{amd} (AMD).

The first and most important condition is the amount of parallelism that can be obtained in the algorithm. For the current generation GPUs, the number of threads should ideally be of an order 10,000 or higher per GPU. Future GPUs will be even more parallel, and this requirement will further increase. Generally speaking, for Monte Carlo simulations there are two (easy) methods to increase parallelism: increase the system size and let more threads work on one system, or increase the number of statistically independent systems and run them in parallel. The second option is easy to implement, but often for the desired system size the simulation will either consume too much memory, or time scales that can be achieved are too low, which is especially important in the case of non-equilibrium models such as PCPD.

Having more threads working on the same system typically relieves these problems, but it is harder to program and it adds synchronization cost to the total computation cost, which can be severe if all threads on the GPU are synchronized.

On a GPU the \textit{workitems}, which are called threads on a CPU, are divided into workgroups. The programmer can decide on the size of a workgroup, up to a maximum that depends on the hardware. Synchronization and communication between workitems within a workgroup is cheap on the GPU, compared to synchronization and communication between two workitems that belong to a different workgroup. To reduce communication overhead, in our implementation each workgroup simulates its own independent system with a different seed of the random number generator (RNG).

Attaining a high memory bandwidth utilization is another aspect of an efficient GPU algorithm. The memory bandwidth of a current-gen high-end GPU (AMD Radeon HD7970, 260 GB/s) is about 5 times higher than that of a current-gen high-end CPU (Intel Core i7 3960X, 51 GB/s). However, the memory access pattern is more important on a GPU; a bad access pattern such as random access will hurt the performance on the GPU more than on the CPU. Sequential access gives the best performance, but the PCPD problem requires us to randomly select a lattice site, which is an inefficient memory access pattern. We circumvent this by slightly modifying the PCPD algorithm. The lattice is divided among the workitems into parts of equal sizes. Then as a compromise, we modify the PCPD algorithm such that all workitems access the same local site in their part of the lattice, where the local site is the site relative to the appointed part of the lattice. The local site for all the workitems is still randomly chosen. Local sites with the same number can be placed sequentially, and the random access pattern becomes at least partially sequential. A more detailed description of how the lattice sites are ordered in memory will be given in section \ref{sec:multi}.

Since the reaction-diffusion models are simulated using Monte Carlo algorithms, it is important to carefully choose the random number generator (RNG). One aspect that determines the quality of a good RNG is the number of bits that is used to store the current state of the RNG. There is a comparatively large, but still limited amount of general purpose registers (GPRs) available on the GPU. Access to these registers is in principle without delay, barring some restrictions that are handled by the compiler. To optimize for performance we chose the combined Tausworthe RNG with the seeds from Ref. \cite{lecuyer99}. It has a 128-bit state storage, which can easily fit inside the GPRs. To verify that this does not deteriorate the results, we used the WELL512 RNG with a 512 bit state space, to check whether the results are influenced by the small state space. We found that this is not the case.

The final important consideration that we want to highlight is the use of branching on the GPU. Workgroups on the GPUs of both NVIDIA and AMD are divided into (smaller) entities called warps by NVIDIA and wavefronts by AMD. These warps/wavefronts are executed in SIMD (Single Instruction Multiple Data) fashion. This means that each workitem in a warp/wavefront executes the exact same instructions. Instructions within a branch are executed by all workitems within a warp/wavefront if at least one workitems takes that particular branch. In addition to that, older AMD GPUs (prior to the Core Gen Next architecture) have a high latency penalty when encountering a branch, which is at least $\sim 50$ clock cycles. In our implementation all branching operations in the simulation part of the program are replaced by bit-operations.

\section{The multispin GPU program} \label{sec:multi}

Multispin programming is a technique that enables parallelism within one thread. It can be used when the number of bits necessary to store one data element is smaller than the register size of the underlying hardware. For example, modern 64-bit CPUs have 64-bit registers (not counting SSE, AVX extensions), whereas current GPUs work fastest on 32-bit integers/floating point numbers. For the reaction-diffusion models that we consider, a lattice site can either be occupied, denoted by 1, or empty, denoted by a 0. Thus, to store the state of one lattice site, we only need one bit of storage per site. In the original multispin technique, parallelism is obtained by simulating $N_r$ lattices in parallel, where $N_r$ is the number of bits in the GPR, depending on hardware. The sequential program is translated to use bit operations, instead of branching statements. Finally, the lattices are decoupled in some way, to ensure that after sufficient time, the $N_r$ lattices are statistically independent.

We opted for a slightly different approach. The problem with the classical approach to multispin programming in the case of GPUs is twofold. Firstly, the multispin technique does not make time steps go faster, but only improves the statistics of the results. Thus, to obtain long time series, we still need to wait a long time, although the statistics are much better than on a CPU, because of the number of lattices used. Perhaps more importantly, the necessary amount of memory grows very large. In our simulations we used a lattice size of $L=2^{18}=262144$. With $500$ workgroups, the total amount of memory used would be about $2$ GB of memory. Although professional Tesla, or FireGL cards usually contain this amount of memory, it does reach the limit of most consumer cards (which are used extensively in simulations because of the price difference), and it does not leave much room for increasing the lattice size.

Instead, we connected the $N_r$ lattices of the classical approach, to form one larger lattice. A concern that may arise, is that the correlation between the sites within one GPR (that of one workitem) will propagate and bias the results. We found that this is indeed the case if sites in the same GPR are close to each other, but if they are the maximum distance apart ($L/N_r$), we found no bias, as a consequence of this trick to increase the lattice size. Additionally, we added extra decoupling between sites in the same GPR, which will be discussed in section \ref{sec:dif}.

\begin{figure}\centering
\includegraphics[width=10cm]{./pics/mem_conf.eps}
\caption{A schematic picture of the memory layout of the multispin GPU algorithm. The configuration shown in this figure has a work-group size of 64. The number of local elements is 32. Consequently, the lattice size is $L=32\cdot 32\cdot64 = 65536$. The work-item number is given by $p_{i}$. The local memory index is denoted by $l_i$. The numbers in the boxes give the global lattice site number, which means that $s=1$ is a neighbor of $s=2$, etc. The arrows indicate lattice sites that are next to each other in the global memory of the GPU. The vertical columns are not drawn, because they are the same as in figure \ref{fig:mem_dist}, i.e. only the first bit of the double word is shown. For example, global lattice site 2048 is contained in the same double word as 0.}
\label{fig:mem_conf}
\end{figure}

\begin{figure}\centering
\includegraphics[width=10cm]{pics/mem_distr.eps}
\caption{A schematic figure showing the distribution of the sites of the lattice among the work-items. The work-item number is given by $p_{i}$. The local memory index is denoted by $l_i$. The numbers in the boxes are global site numbers, where $s=1$ is a neighbor of $s=2$, etc. The arrows indicate consecutive lattice sites. A vertical column is stored in one double word, and this is where multispin coding is used.}
\label{fig:mem_dist}
\end{figure}

The placement of the sites in memory is shown in figures \ref{fig:mem_conf} and \ref{fig:mem_dist}. This memory lay-out is optimized for performance. At each step of the simulation of the reaction-diffusion model, the GPU program loads a number of consecutive sites into the GPRs of each workitem. The sites loaded from the global memory are those that are needed for computation of the Monte Carlo step, and those that can potentially be modified. Thus, for the PCPD problem, four sites loaded into the GPRs (the pair, one to the left of the pair and one to the right). For a equivalent definition of the TCPD problem, five sites would have to be retrieved. The workgroup size is chosen to be a power of 2, such that the memory loads are $4 \cdot S_w$ byte aligned, with $S_w$ the size of the workgroup. According to a technical document of AMD \cite{amd}, the memory channel width of AMD GPUs is 256 byte, and we expect at least decent performance, using a workgroup size of $64$.

The distribution of work among the workitems in combination with the memory lay-out ensures that there is no communication needed between workitems: the sites on which the workitems work are always far enough ($L/N_r$) apart such that they are independent within a step. The sites are stored in the (shared) global memory, which also prevents the need for communication, as opposed to using the GPRs. Between computation steps, however, it is necessary to synchronize the workitems within a workgroup to avoid race conditions on the global memory. If the workgroup size is small enough, this synchronization is a intrinsic property of the SIMD array of the GPU and in that case it is cost-free (64 for AMD GPUS, 32 for NVIDIA GPUs).

\subsection{Implementation details of the PCPD algorithm}

\begin{algorithm}[tb]

	\caption{GPU multispin PCPD algorithm}
	\begin{algorithmic}[1]\label{alg:pcpd_gpu}

	\STATE \textbf{Input: } Local lattice $l$ at time $t$, site(s) $i$, percolation probability $p$.
	\STATE \textbf{Output: } Local lattice $l$ at time $t+1/32$.
	\STATE \textbf{Call: PCPD\_GPU\_multi}($L$, $i$):

	\medskip
	\STATE \COMMENT{Diffusion, $d=0.5$}
	\STATE $\mathrm{dMask} := \mathrm{RNG()}$
	\STATE $\mathrm{temp} := l[i]$ \label{all:drest}
	\STATE $l[i] := (\mathrm{dMask}\land l[i+1]) \lor ((\lnot \mathrm{dMask}) \land l[i])$
	\STATE $l[i+1] := (\mathrm{dMask}\land\mathrm{temp}) \lor ((\lnot \mathrm{dMask}) \land l[i+1])$ \label{all:drestend}
	\medskip
	\STATE \COMMENT{pMask has the $j$-th bit set to 1 iff the $j$-th bit in both $l[i]$ and $l[i+1]$ are 1}
	\STATE $\mathrm{pMask} := l[i]\land l[i+1]$
	\medskip
	\STATE \COMMENT{Annihilation, $p<0.25$}
	\STATE $\mathrm{aMask} :=$ RNG() $\land$ RNG() \label{all:dec}
	\STATE $\mathrm{aMask} := (\lnot \mathrm{dMask}) \land \mathrm{aMask} \land \mathrm{pMask} \land  (({\rm RNG}()< 4 p)?1:0)$ \label{all:glob}
	\STATE $l[i] := l[i] \land \mathrm{aMask}$
	\STATE $l[i+1] := l[i+1] \land \mathrm{aMask}$
	\medskip
	\STATE \COMMENT{Fission high}
	\STATE $\mathrm{fMask} := \mathrm{pMask} \land  (\lnot \mathrm{dMask}) \land (\lnot \mathrm{aMask}) \land \mathrm{RNG()}$ \label{all:fis_start}
	\STATE $l[i+2] := l[i+2] \lor \mathrm{fMask}$
	\medskip
	\STATE \COMMENT{Fission low}
	\STATE $\mathrm{fMask} := \mathrm{pMask} \land  (\lnot \mathrm{dMask}) \land (\lnot \mathrm{aMask}) \land (\lnot \mathrm{fMask})$
	\STATE $l[i-1] := l[i+2] \lor \mathrm{fMask}$ \label{all:fis_end}
  \end{algorithmic}
\end{algorithm}

To keep the pseudocode compact and more easy to follow, we assume that the required sites are already loaded from the global memory into the GPRs, and that the necessary bit-rotations to connect the multi-spin lattices are already done.

The PCPD-specific core of the algorithm is given in Algorithm \ref{alg:pcpd_gpu}. The bitwise operations used are the \textbf{or} ($\lor$), \textbf{and} ($\land$) and \textbf{not} ($\lnot$) logical operators. Except for the comparison in line \ref{all:glob}, the pseudocode can be read as if it were only working on one bit. In the processing unit of the GPU these bit-wise operations are done on all $N_r$ bits simultaneously. Line \ref{all:glob} is an exception: the comparison ${\rm RNG}()< 4 p$ is not done bit-wise. Instead, it gives either 1 or 0 equally for all $N_r$ bits. The reason for this will be given in section \ref{sec:anni}.

\subsection{diffusion} \label{sec:dif}

In algorithm \ref{alg:pcpd_gpu} the diffusion coefficient $d$ is set to $0.5$. In contrast to a straightforward PCPD implementation, the value for $d$ is hard coded for efficiency. The advantage lies in  the computational effort to create a bit that is one with probability $d$. For $d=0.5$ the output of the function RNG$()$ (with a correct implementation of the RNG) is 1 with probability $0.5$, and 0 otherwise. To obtain other values for $d$ \textbf{or} and \textbf{and} operators are used. For example to create bits that are 1 with probability $0.25$ the \textbf{and} operator is used between two random numbers: $\mathrm{dMask} = \textrm{RNG}() \land \mathrm{RNG}()$. This way we can generate $2^{N_g}-1$ different values of $d$ using at most $N_g$ calls to the RNG ($d=0$ is not counted). The universal behaviour of the system is believed to independent of $d$, and therefore the limited choice of $d$ is not an issue, as long as we can select values for $d$ that differ sufficiently.

In lines \ref{all:drest}-\ref{all:drestend} the diffusion step is done by swapping the bits of sites $l[i]$ and $l[i+1]$, if the bit in $\mathrm{dMask}$ is 1.

\subsection{Annihilation} \label{sec:anni}

In the annihilation step we are confronted with a similar problem as in the diffusion step. We need to create a set of $N_r$ bits that are one with probability $p$. We could do this analogously with the diffusion step, but in this case an arbitrary value for $p$ is not useful, because $p$ needs to be close to $p_c$. In our simulations in Ref. we found $p_c$ with an error of approximately $2 \cdot 10^{-6}$, which means that we would need at about $18$ random numbers to have multiple values of $p$ close enough to $p_c$ ($2^{-18} \approx 4\cdot10^{-6}$). The final PCPD program needs 5 or 6 random numbers in total, depending on $d$. Thus, it would be a bottleneck if we would use the same procedure for the annihilation step. Instead, all $N_r$ bits are set to 1 with probability $p$ and all 0 otherwise. This gives each bit the right probability to be 1, but the bits are fully correlated. With the described memory lay-out in section \ref{sec:multi} we found the bias due to the correlation to be smaller than the noise of our data, but to be safe we added a decorrelation step to our algorithm.

We found in Ref. \cite{schram_pcpd} that $p_c<1/4$ for $d=0.25$, $d=0.5$ and $d=0.75$. In line \ref{all:dec}, $N_g$ bits are generated independently of each other being 1 with probability $0.25$. Then in the next line we apply the \textbf{AND} operator between these bits and the fully correlated bits that are one with probability $4 p$. The result is a partially correlated bit with probability $p$ to be one. In the case that we would not have the property $p<1/4$, we can still do a similar procedure. For example, in the case of the bound $p<3/4$, we would generate uncorrelated bits with a probability of $3/4$ to be 1, and use the \textbf{AND} operation with correlated bits that are one with probability $4p/3$. The quality of the decorrelation procedure depends on the tightness of the bound we use.

The last two lines clear the two sites $l[i]$ and $l[i+1]$ under the following conditions:

\begin{enumerate}
 \item $l[i] = l[i+1] = 1$
 \item No diffusion this step
 \item We drew 1, with a probability $p$
\end{enumerate}

\subsection{fission}

Lines \ref{all:fis_start}-\ref{all:fis_end} constitute the fission step. By the definition given in eq. (\ref{eq:rates}), the conditional probability to attempt a fission step, given that no diffusion or annihilation step was attempted, is 1. Therefore, only one random number is necessary to distinguish between a new particle to the left and to the right of the pair.

\section{Benchmarks}

\subsection{Test setup}

We use the ``Little Green Machine'' for our main benchmarking tests. A node consists of two NVIDIA Geforce GTX 580 GPUs, an Intel Xeon E5620 (@2.4 Ghz) CPU, and 24 GB of memory. As the OpenCL library we use the NVIDIA Cuda toolchain, version 4.0. The program was compiled using version 4.1.2 of the gcc compiler, with optimization flags -O2.

Additionally to this setup, we also use a PC, consisting of an ATI Radeon HD5850 GPU, an Intel Core 2 Duo E8400 (@3.0 Ghz), and 4 GB of memory.

\subsection{Performance}

The performance of the GPU PCPD algorithm is measured in the number of moves done per second globally on the GPU, including multispin. In the PCPD case the program reads 4 bits, and writes back 4 bits to the lattice, per single move. Thus the total (read/write combined) bandwidth in bytes/s (B/s) of the PCPD program is equal to the number of moves/s. The performance of the PCPD GPU program is shown in figure \ref{fig:perf}, for different GPUs and a CPU.

Our conventional CPU program does roughly $20 \cdot 10^6$ moves per second, which means that the GPU program is about 4000 times faster. The same GPU program run on the CPU performs $615 \cdot 10^6$ moves per second, which is still 130 times slower than the same algorithm run on a GPU. Using both cores, the algorithm achieves almost perfect scaling with $1200 \cdot 10^6$ moves per second. Thus, we conclude that this algorithm is very well tailored for the GPU. We believe that this is due to the fact that the algorithm is still computationally bound, where the GPU has the largest architectural advantage. Also, the GPU algorithm on the CPU has the disadvantage that the memory access pattern is more simlar to a random access pattern.

The performance depends on the size of the workgroups on the GPU. The advantage of a smaller workgroup is that synchronization is less expensive. Also, the number of workgroups that fits on a compute unit/SIMD array concurrently is larger because the stacking of workgroups is less coarse grained. In our implementation the number of bytes read sequentially is equal to $4 S_w$. The more bytes that are read sequentially, the better the global access pattern, which can improve performance. With a workgroup size of 32 we are likely seeing this effect: even with the largest number of workgroups, it is still 20\% slower than the simulations with larger workgroup sizes. Since less workitems per workgroup makes the simulation more safe with regards to finite size effects, the best choice is probably either $WS=64$ or $WS=128$.

\begin{figure}\centering
\includegraphics[width=10cm]{pics/nwg_bench.eps}
\caption{Performance of the GPU PCPD algorithm, depending on the number of workgroups and the size of the workgroups. The performance is measured in the effective bandwidth the algorithm achieves. For the PCPD problem, the number of bytes transfered per second is equal to the number of moves per second. The number of workgroups is equal to the number of parallel lattices on the GPU. The smallest workgroup (WS=32) has the worst performance. However, it has theoretically the most numerically most accurate results. Thus, for safety for our analysis \cite{schram_pcpd} we used a workgroup size of 32. The fact that the graph is not smooth, is not due to statistical fluctuation. The error bars on the curves is much less than 1 GB/s. Instead, the reason is that the performance does not depend smoothly on the number of workgroups, because the number of computational units is an integer. We will not discuss more deeply why some workgroup size is better performing than others.}
\label{fig:perf}
\end{figure}

To test the numerical dependence of the density $\rho(t)$ on the workgroup size and the number of decorrelation bits, we have used different configurations of those. Only with the largest workgroup size (512) there is a significant deviation from the other curves. Adding decorrelation bits does not help to improve the numerical result. This means that the cause of the deviation is the choice of sites, which is correlated between the workitems (and which is not influenced by decorrelation bits). On the other hand, a workgroup size of $128$ is indistinguishable from runs with $S_w=32$. Thus, we conclude that our data with $S_w=32$ is almost certainly not significantly biased by the finite lattice size.

\subsection{Analysis}

The analysis was done in a previous paper \cite{schram_pcpd}. Here, we will present some analysis of the data to show the necessity of a fast algorithm.

At the critical value $p_c$, the density $\rho$ of the system is expected to decrease in a power-law fashion. However, for the PCPD problem we found that there are strong corrections to scaling, which we believe to be of the following form:

\begin{equation}
 \rho(t) = c_1 t^{-\delta} + c_2 t^{-2 \delta} + \ldots.
\end{equation}

As shown in the analysis paper, under this assumption, asymptotically a straight line is obtained by plotting $\delta_{\rm eff}$ as a function of $\rho$. This is one in figures \ref{fig:delta_0.25} and \ref{fig:delta_0.75} for diffusion coefficients $d$ equal to 0.25 and 0.75 respectively. The figure with $d=0.5$ was shown in the analysis article. The particle density and the pair density are expected to converge to the same value of $\delta$ at $\rho=0$ (or equivalently $t \rightarrow \infty$). The pair density and the particle density at high densities (low $t$) have slopes that when extrapolated, cross each other at some finite density. Thus, at these time scales, it is not possible to extract the universal exponent $\delta$ by extrapolation. The data after the virtual crossover point is more useful in this regard, but even with the amount of data gathered, this part is still quite noisy and short. This shows the necessity of a fast algorithm as presented in this paper.

\begin{figure}\centering
\includegraphics[width=10cm]{pics/delta_eff0.25.eps}
\caption{The effective exponent $\delta_{\rm eff}$ for both the single particle density (black lines) and the pair density (gray lines), as a function of their respective densities. The diffusion constant $d$ is equal to $0.25$. The values for $p$ was chosen close to the critical point, that was estimated to be $p_c = 0.125141(2)$. The lattice size was chosen to be $L=2^{18} = 262144$. The values for $p$ are 0.12514 ($N=2000$), 0.125142 ($N=3000$), 0.125145 ($N=3000$) and 0.125155 ($N=1000$), with $N$ the number of runs.}
\label{fig:delta_0.25}
\end{figure}

\begin{figure}\centering
\includegraphics[width=10cm]{pics/delta_eff0.75.eps}
\caption{The effective exponent $\delta_{\rm eff}$ for both the single particle density (black lines) and the pair density (gray lines), as a function of their respective densities. The diffusion constant is equal to $0.75$. The values for $p$ was chosen close to the critical point, that was estimated to be $p_c = 0.191789(2)$. The lattice size was chosen to be $L=2^{18} = 262144$. The values for $p$ are 0.19178 ($N=2000$), 0.191785 ($N=2000$), 0.19179 ($N=8000$) and 0.191795 ($N=2000$), with $N$ the number of runs.}
\label{fig:delta_0.75}
\end{figure}

\section{Conclusion and discussion}

We have addressed concerns about the numerical accuracy, as a result of an insufficiently large lattice, in combination with a large workgroup size. We conclude that the effective lattice size does indeed decrease with an increasing workgroup size. Thus, the effective lattice size will be smaller than the number of sites in the lattice. This means that the lattice size has to be bigger than in an ordinary CPU simulation. However, the simulations presented here were not limited by the amount of memory, and for workgroup sizes smaller than $128$, we did not observe any deviation at all, with a lattice size of $2^{18}$, and $t<1.5 \cdot 10^{7}$.

The GPU reaction-diffusion algorithm presented here is much faster than traditional multispin methods, which are among the fastest CPU methods.  With our algorithm, one GPU is roughly equivalent to $130$ CPU cores. A multispin program specifically written for the CPU will be faster, but it is unlikely to be much more than twice as fast (most can be gained from going from 32-bit integers to 64-bit integers), which still leaves a factor of roughly $65$. Thus, it greatly sped up the simulations used to analyze the PCPD model, which otherwise would have taken an immense amount of CPU hours.

The algorithm is easy to extend to other related models, and is already being used for that problem. Hopefully this will shed more light on the issue of universality in non-equilibrium statistical mechanics models.

\section{Acknowledgements}

Computing time on the ``Little Green Machine", which is funded by the Dutch
agency NWO, is acknowledged.

\bibliographystyle{ieeetr}

redpajama_set_name: RedPajamaArXiv


Christine Clayfield is an author. She has written a wealth of non-fiction business books. Now, she is taking a step into the world of novels with the release of her book No Fourth River. She wanted some fresh personal branded headshots that would support her move.
I met Christine through Janet Murray's recent Media Influence Live event. As official photographer for this conference, Christine got to know me as one of the delegates.
Janet is going to be hosting another event later on this year. To get all of your content planned out in the right way for 2019, you need to be at Content Live! See ya there!
Christine's existing headshot is formal. This time she wanted to capture something more relaxed and casual.
Unlike my usual headshots packages, I worked on developing a specific headshots service for the Media Influence Live delegates with Janet in the run up to the event. Christine chose to shoot with me in one of my quicker services, inside The Trampery, where Media Influence Live was happening.
After the first day of Media Influence Live came to an end, it was time for Christine and I to shoot.
The Trampery is a wonderfully quirky space. It's pure Hoxton! I instantly found some great nooks and crannies around the building to set up for Christine's headshot.
Great colour in the boardroom.
We both loved this textured cork wall.
You can see we went with a Black and White option on some of Christine's final shots. The reason for this was twofold. Christine has a scar that is pertinent to her story in No Fourth River, and I felt that black and white would show this in a more defined way. The other reason for doing this is to support publishers. Authors and writers always need to have great black and white versions of their headshots to be used in book inlays. On a lot of occasions this is the preferred format of an "about the author" synopsis. Take a look at a nearby book in the first couple of pages and you will see instantly what I mean.
Christine decided that she would like to pick her own photography. To ensure that we got this exactly right we made her a VIP online gallery space where she was able to select which of her headshots were her most favourite. From this we worked on the final collection and agreed that some black and white versions would be perfect for her author inlays on any future books.
I would officially like to thank The Trampery for being so accommodating on this session. Next time I'm in London this is where I'm working from. Take a look at their upcoming events.
If you are going to an event that you KNOW I'm going to be shooting at, we need to get in touch so that I can keep you informed of all the details.
Head directly to my list of travels in this link, and put yourself on the relevant earlybird list to stay at the front of the queue for your next headshots.
If you would like to turn the dial up to 11 on your next headshots session, you might prefer to shoot outside of the time confines of an event. Take a look at my latest brochure that includes all of my regular headshots services.


You have to fill in this document with data relevant for your project and send it to responsible JTS manager, who will process it. After this document is signed by the Head of JMA it will be sent by post to the Beneficiary or Ukrainian Partner, who will submit it to the MEDTU itself.
This document has to be prepared and signed by the Ukrainian Beneficiary and/or each Ukrainian Partner (only Ukrainian project partners have to submit this document). Later on this document(s) must be submitted to the MEDTU together will all annexes listed in it.
This document has to be signed by the Head or Deputy Head of the relevant Oblast Administration depending on location of the project's Ukrainian Beneficiary or Ukrainian Partner or the project target area. Later on this document must be submitted together with all other documents to the MEDTU.
We propose to send all the above required documents in one single package to the MEDTU.


Find all the USCIS local office details for Houston. B-2 Tourist Visa Application B-2 please contact the METRO Assistance Center at 713-635-4000 or visit the... Articles in this section. How do I log back in to my Russia Visa application? On the Russia visa application, is "Center ILS (Washington) the same as Embassy of Russia?
Save yourself the time and hassle Let our experienced travel team prepare your visa application for you. See how this works... Washington DC. 01/31/17 06:59 PM. you would need to pick it up at the ILS office in the financial district . You have made the visa application much easier!
2012-07-11 · Russian Visa through ILS in NY - Moscow between going to ILS in person and "dropping off" docs for your visa application Us Help Center.
BUSINESS REQUIREMENTS FOR RUSSIA VISAS: One completed, printed and signed online Russia visa application. Submit "ILS Washington."
Apply for Visa to China. chinese Visa Application and requirements. Visa to China Application Center. 1-877-203-2551 China Visa Washington.


text:
Q: How to exclude events with low data (eg. threshold, outliers) I have this data set and I want to filter only "Event" with a good conversion rate.
We can say that good are those that have a higher than average conversion (but maybe you have better ideas).
Since the average conversion is 0.8% I will also select those events with too little data (eg Impressions = 1 or impressions = 10).
What formula can I use to quickly exclude events with too little data and set a minimum threshold for impressions?
I can't use an hard-coded threshold because it has to be different for each account.
Impressions/clicks are not normally distributed. Maybe long-tail distribution makes more sense.

A: Without knowing more about your objective, it is difficult to suggest
a suitable criterion that could be used for all accounts. But here are some ideas. [Computations in R.]
In your example, 'impressions' are
x = c(1563, 400, 100, 1400, 1, 10)

Sorted data are
sort(x)
[1]    1   10  100  400 1400 1563

So you might throw out a row in your table if: (a) the impression count
is to low to matter, perhaps below 20; (b) the impression count is among a client's
lowest 25% of impressions, which is below about 30 in your example;  (c) if
the number of impressions is a low outlier,
which in your example, disregards nothing. (I'm using the "boxplot 1.5 IQR rule" for outliers.) This would work better with more data, say at least a dozen rows.)
quantile(x, .25)
 25%
32.5

boxplot(x, horizontal=T)

Then, having disregarded rows with too few impressions, you might use another
criterion to pick "relatively good" conversion rates for each client.
In your example, suppose now that rows F, G, and H are gone on account of
low impression counts.
That might be anything: (a) at or above the median (1.3); (b) at or above the 75th quantile (10); (c) more than one SD above the mean (18). [Even if you had enough data to show outliers, I think requiring a high outlier in order to be
called "reasonably good" is too harsh a test.]
y = c(1.3, 10, 24, .4, .5)
median(y);  quantile(y, .75)
[1] 1.3
75%
 10
mean(y) + sd(y)
[1] 17.43819
mean(y)
[1] 7.24

[Notice that with rows F, G, and H gone, the average conversion rate is now
down to 7.24.]
Even if you don't like my specific suggestions, based on quick orientation and only one dataset, maybe you will find something useful in the general approach.

redpajama_set_name: RedPajamaStackExchange


K2M started in Eric Major's garage in Ashburn, inventing and producing instruments for doctors to use in spinal surgeries, with Major and his co-founder, John P. Kostuik, a former chief of spine surgery at The Johns Hopkins University School of Medicine.
That was in January 2004. By September of that year, K2M had moved from a temporary office near Dulles Airport to a small office in the corner a nondescript building on Miller Drive in southeast Leesburg.


From small projects that streamline operations, to large-scale transformations of an organization's data security program, blockchain is providing practical benefits to a broad range of industries and organizations today.
FTI Technology's Information Governance, Privacy & Security (IGP&S) practice provides a range of blockchain advisory services. No matter where a company is in its strategy development or execution, the FTI team has a strong track record of collaborating across legal, security, IT, compliance and lines of business to ensure input and transparency with key stakeholders on policy development and implementation.
Blockchain can improve current business processes.
We can test and implemement blockchain programs for maximum effectiveness.
Blockchain can provide cost savings and other benefits for the organization.
We can identify the best use case and blockchain technology to develop.
Given the company's needs and environment, identify the best technologies.
Design and implement compliance programs to adhere to specific legal or regulatory requirements or industry best practices.
Our global team of professionals – comprising blockchain experts, former regulators, cyber security leaders, forensic investigators, law firm counsel, litigation support, in-house counsel and IT – provide your company with technical expertise, legal and regulatory experience and effective program execution. To learn more, please contact blockchain@fticonsulting.com.
1 Report: The Future of Blockchain: Key Vertical Opportunities & Deployment Strategies 2018-2030" by Windsor Holden, Juniper Research, August 1, 2018.
2 "Here's What Two Executive Surveys Revealed About Blockchain Adoption," by Lucas Mearian, Computerworld, August 28, 2018.


Fun-loving, bombastic, and one heck of a BBQ pitmaster are descriptors that manage to only scratch the surface of Mr. Neil "Bigmista" Strawder – pitmaster at Bigmista's Barbecue. Together with his wife Phyllis, he's built up a West Coast BBQ following and garnered quite a bit of national, and international attention as well.
Neil and Phyllis are a BBQ Power Couple, with each lending their particular skills to the businesses Bigmista's BBQ is building. Currently, there are two restaurants – The Sammich Shop in East Long Beach, CA and Bigmista's Morning Wood in Lakewood Village, CA. Word is that a third is in the works.
The Origins of Bigmista's BBQ on Video!
Check out this clip from Made Man, where Neil and Phyllis share the origins of their BBQ business. "Don't cut into my shoe money!" Love it.
FUN! And that's what you get from Neil in this podcast session. Next time, we're going to do a conference call with both he and Phyllis. Oh man… the wheels are turning now!
Let's start with the Big Close Out… wow. If they close the shop down like this every day, it's going to become an event to mark on the calendar!
You can also get a great look into the BBQ operations over at The Sammich Shop by checking out the "Light It Up" episode of Man Fire Food with Roger Mooking on Cookingchannel.com.
In this conversation with Neil Strawder, you'll learn about his beginnings in BBQ – cooking as part of a competition team called 4Q BBQ. 4Q! No… 4Q!!!! Haha. Great name. Eventually, Neil began to sell BBQ at local area farmer's markets, where he grew a strong and loyal following. This following and the success it brought led the Strawders to open up their restaurants, where business continues to do very well.
OK… let's get on with the session notes. Remember, you can click on the time stamps to hear the segment it relates to.
[spp-timestamp time="4:00″] We go back with Neil and trace his BBQ journey starting in Texas as a kid… it's a fun trip. Nice mention of the role the BBQ Brethren played here, too.
[spp-timestamp time="11:50″] Catering gets serious, and doing BBQ as a business gets rolling. The real story of the push in this direction – those competitions were starting to cut into Phyllis' shoe money! Mista did his Michael Jackson and split away to compete under Bigmista's Barbecue. Slyvie Currie competes now as Lady of Q – check this story.
[spp-timestamp time="13:46″] Phyllis suggests vending at some local farmer's markets and the LA Times' food editor sparks some serious attention among foodies for Bigmista's Barbecue.
[spp-timestamp time="15:18″] Taking that leap of faith! Neil shares what it was like when he and Phyllis deal balancing his job at Wells Fargo with the increasing demands of the success they were having in BBQ.
[spp-timestamp time="17:12″] Learn what Neil did to cement his decision to never go back to having "job" … hing – it involved FIRE!
[spp-timestamp time="19:00″] Learn a bit about how doing business at farmer's markets works… interesting info from Neil here.
[spp-timestamp time="20:41 "] The first restaurant venture gets underway…. then doesn't. A lesson in what to look for, and who – if anyone – to partner with. Then the Long Beach location opened up at the site of a former Italian bakery.
[spp-timestamp time="30:00″] Learn a bit about some of the projects Neil has going on, including how he got started with the folks at CABO WABO Tequila.
So there you have it. Neil "Bigmista" Strawder in all of his humor and style. If you're in the Long Beach, CA area be sure to check out one or both of his family's restaurants.


In collaboration with The Hans Foundation (THF), we organized our annual THFFFE Open House at College of Technology, Pantnagar for the second consecutive year. Mr. Vijay Jamwal – Director, Program and Evaluation, The Hans Foundation and Mr. Sunil Tiwari  General Manager and Head of Manufacturing, Ashok Leyland, Pantnagar were the Guests of Honor. 87 scholars from Pantnagar and surrounding regions attended the event where scholarship certificates were distributed to 65 THF – FFE scholars.


text:
Q: How to change the header background of a GroupBox? How can I change the Background of the header of a GroupBox?
I'm trying to do that with:
<GroupBox Grid.Row="0">
   <GroupBox.Header>
       <Setter Property="Background" //<- no backgroundproperty

there is no Background property

A: You can define a Border in the Header and set the Background of it to your desired color:
<GroupBox >
    <GroupBox.Header>
        <Border Background="Red">
            <Label Content="Hello"></Label>
        </Border>
    </GroupBox.Header>
</GroupBox>

A: You could set the Header property to any UI element including a Grid or a Border for example:
<GroupBox>
    <GroupBox.Header>
        <Border Background="Green">
            <TextBlock Text="header..." />
        </Border>
    </GroupBox.Header>
    <TextBlock Text="content..."></TextBlock>
</GroupBox>

A: Take a look at this site: Control Templates, Styles, and Triggers
this is probably more than you need, but it explains how to use a control template to modify controls in various ways. I use this particular control (with different colors) for groupboxes on one of my applications, and it has come in very handy.


text:
Hrabství Louth (, ) je irské hrabství nacházející se na severovýchodě země v bývalé provincii Leinster. Sousedí s hrabstvím Monaghan na severozápadě, se severoirským hrabstvím Armagh na severu a s hrabstvím Meath na jihozápadě. Východní pobřeží omývá Irské moře.

Hlavním městem hrabství je Dundalk. Druhým největším a nejvýznamnějším městem je Drogheda. Hrabství má rozlohu 826 km² a žije v něm 122 808 obyvatel (2011). Hrabstvím protéká řeka Boyne.

Mezi zajímavá místa hrabství patří Monasterboice.

Dvoupísmenná zkratka hrabství, používaná zejména na SPZ, je LH.

Externí odkazy

 Oficiální stránky

Louth
Louth

redpajama_set_name: RedPajamaWikipedia


If there's a user in your team who you'd like to receive email notifications, you can have the Account Owner enable this in the User Settings and Notification Preferences panel.
If the team member doesn't already have a Brandboom login, they will need to create one. There isn't a way to send emails to team members who are not set up on Brandboom.
Please note that if the user is Free, they will have a limit of 10 email notifications per month.


This month, Paul Harmon gives us a glimpse of what BPM practitioners can look forward to in the coming years, and Alan Ramias recounts his first assignment as an "internal improvement consultant in the 1980"s. As always, we hope you find all of the content of interest and useful to you in your BPM practice. Please let us know.
Please plan to attend Paul Harmon's webinar titled The World of Business Transformation, on Tuesday, July 25 at 11AM EDT.


So You Want to See Me Up Close and Personal?
I was just thinking about you and Ronnie. Carol and I are talking abut attending the Womyn's Music Festival this summer. I see that you perform on Tuesday and I'm not sure We can get there for your performance, however We would still like to see the two of you. Maybe we can set something up while you're in Michigan. We were going to try to come to the festival over the weekend.


ACCELERATED PD: The Learning Accelerator, a nonprofit working to support the implementation of blended learning, has invested another $1 million in funding to support professional development for teachers and principals doing blended learning. This investment is the second round of investments made by TLA in the human capital sector. In April 2014, the organization invested $2 million in four different organizations.
This round, only one organization received a follow-up grant, with two other newcomers to the TLA human capital portfolio.
The grants are intended to help teachers and principals bring blended learning to their schools effectively. The Learning Accelerator hopes these organizations will serve as models of how to create and provide professional development.


A young virgin couple are finally wed.
Each one is nervous about the impending night, but neither are willing to admit or ask each other about it. Wondering what to do first, the young man calls his father. "Dad, what do I do first?" "Get nak*d and climb into bed," his father replies.
So, the young man does as he is advised.
The girl is mortified and calls her mama. "Get nak*d and join him," is the advice from mama, so she complies. After laying there fora few moments, the young man excuses himself and calls his dad again. "What do I do?" he asks.
His father replies, "Look at her naked body. Then, take the hardest part of your body and put it where she pees!" is the dad's advice.
A few moments later, the girl again calls her mama. "What do I do now?" she asks. "Well, what is he doing?" mama asks. "He's in the bathroom, dunking his head in the toilet!"


Mr. Media is recorded live before a studio audience of unruly local TV journalists who know it all but only have 30 seconds – and perfect hair and teeth – to explain it to you, the home viewer… in the NEW new media capital of the world… St. Petersburg, Florida!
I was a crappy office manager.
I had my shot back in 1988 as managing editor of Tampa Bay Weekly. The alternative newspaper had just been sold and I made a pretty good pitch to the new publisher to step in as editor. In terms of understanding the market and the nature of content the audience would enjoy, I think I had a pretty good handle.
In terms of managing everyone from the production and editorial side to the advertising and circulation staff, eh, not so much.
I had zero experience leading and inspiring others. I was extremely socially awkward, although I had managed to get engaged and was in the midst of planning a May wedding. Little things could easily set me off and I didn't yet see the big picture, the long game, and all those other management clichés.
My boss, the publisher, was based in Minneapolis and only parachuted in once a month, leaving the ad director and I in charge. He offered good advice and direction when he was in town, but we were otherwise on our own.
And the ad director and I didn't get along. That relationship went to hell when the publisher decided he needed one of the only two private offices for himself – even though he was rarely around — and forced us to share a small space. The ad director wanted the door closed at all times because she was on the phone romancing advertisers; I wanted it open so I was accessible to the staff.
It was all moot a few months later when Creative Loafing came to town from Atlanta and crushed us.
In the years since, I have co-authored a number of business and management books. Shockingly, I have made a good living from that work, which is why I had a personal interest in author Jill Geisler's new book, Work Happy: What Great Bosses Know.
The book is drawn from her 20 years of experience running a TV newsroom – starting at the same age I was when I blew my shot in print. The difference is that Jill was really, really good at it.
And because of the Poynter connection and its promotion of stuff like ethics, I will point out that I have done work for Poynter over the years, although I don't think Jill and I have worked together before. Oh, and we're both represented by the same agent, the fabulous Jane Dystel.


text:
<?php

namespace Google\Cloud\Core\Iterator;

use Google\Cloud\Core\ArrayTrait;

/**
 * This trait fulfills the
 * [\Iterator](http://php.net/manual/en/class.iterator.php) interface and
 * returns results as a page of items.
 */
trait PageIteratorTrait
{
    use ArrayTrait;

    /**
     * @var array|null
     */
    private $page;

    /**
     * @var callable
     */
    private $resultMapper;

    /**
     * @var callable
     */
    private $call;

    /**
     * @var array
     */
    private $callOptions;

    /**
     * @var array
     */
    private $config;

    /**
     * @var int
     */
    private $position = 0;

    /**
     * @var int
     */
    private $itemCount = 0;

    /**
     * @var array
     */
    private $resultTokenPath;

    /**
     * @var array
     */
    private $nextResultTokenPath;

    /**
     * @var array
     */
    private $itemsPath;

    /**
     * @var string|null
     */
    private $initialResultToken;

    /**
     * @param callable $resultMapper Maps a result.
     * @param callable $call The call to execute.
     * @param array $callOptions Options to use with the call.
     * @param array $config [optional] {
     *     Configuration options.
     *
     *     @type string $itemsKey The key for the items to iterate over from the
     *           response. **Defaults to** `"items"`.
     *     @type string $nextResultTokenKey The key for the next result token in
     *           the response. **Defaults to** `"nextPageToken"`.
     *     @type string $resultTokenKey The key for the results token set in the
     *           request. **Defaults too** `"pageToken"`.
     *     @type array $firstPage The first page of results. If set, this data
     *           will be used for the first page of results instead of making
     *           a network request.
     *     @type callable $setNextResultTokenCondition If this condition passes
     *           then it should be considered safe to set the token to get the
     *           next set of results.
     *     @type int $resultLimit Limit the number of results returned in total.
     *           **Defaults to** `0` (return all results).
     * }
     */
    public function __construct(
        callable $resultMapper,
        callable $call,
        array $callOptions,
        array $config = []
    ) {
        $this->resultMapper = $resultMapper;
        $this->call = $call;
        $this->config = $config + [
            'itemsKey' => 'items',
            'nextResultTokenKey' => 'nextPageToken',
            'resultTokenKey' => 'pageToken',
            'firstPage' => null,
            'resultLimit' => 0,
            'setNextResultTokenCondition' => function () {
                return true;
            }
        ];
        $this->callOptions = $callOptions;
        $this->resultTokenPath = explode('.', $this->config['resultTokenKey']);
        $this->nextResultTokenPath = explode('.', $this->config['nextResultTokenKey']);
        $this->itemsPath = explode('.', $this->config['itemsKey']);
        $this->initialResultToken = $this->nextResultToken();
    }

    /**
     * Fetch the token used to get the next set of results.
     *
     * @return string|null
     */
    public function nextResultToken()
    {
        return $this->get($this->resultTokenPath, $this->callOptions);
    }

    /**
     * Rewind the iterator.
     *
     * @return null
     */
    public function rewind()
    {
        $this->itemCount = 0;
        $this->position = 0;

        if ($this->config['firstPage']) {
            list($this->page, $shouldContinue) = $this->mapResults($this->config['firstPage']);
            $nextResultToken = $this->determineNextResultToken($this->page, $shouldContinue);
        } else {
            $this->page = null;
            $nextResultToken = $this->initialResultToken;
        }

        if ($nextResultToken) {
            $this->set($this->resultTokenPath, $this->callOptions, $nextResultToken);
        }
    }

    /**
     * Get the current page.
     *
     * @return array|null
     */
    public function current()
    {
        if ($this->page === null) {
            $this->page = $this->executeCall();
        }

        $page = $this->get($this->itemsPath, $this->page);

        if ($this->nextResultToken()) {
            return $page ?: [];
        }

        return $page;
    }

    /**
     * Get the key current page's key.
     *
     * @return int
     */
    public function key()
    {
        return $this->position;
    }

    /**
     * Advances to the next page.
     *
     * @return null
     */
    public function next()
    {
        $this->position++;
        $this->page = $this->nextResultToken()
            ? $this->executeCall()
            : null;
    }

    /**
     * Determines if the current position is valid.
     *
     * @return bool
     */
    public function valid()
    {
        if (!$this->page && $this->position) {
            return false;
        }

        return true;
    }

    /**
     * Executes the provided call to get a set of results.
     *
     * @return array
     */
    private function executeCall()
    {
        $call = $this->call;
        list($results, $shouldContinue) = $this->mapResults(
            $call($this->callOptions)
        );

        $this->set(
            $this->resultTokenPath,
            $this->callOptions,
            $this->determineNextResultToken($results, $shouldContinue)
        );

        return $results;
    }

    /**
     * @param array $results
     * @return array
     */
    private function mapResults(array $results)
    {
        $items = $this->get($this->itemsPath, $results);
        $resultMapper = $this->resultMapper;
        $shouldContinue = true;

        if ($items) {
            foreach ($items as $key => $item) {
                $items[$key] = $resultMapper($item);
                $this->itemCount++;

                if ($this->config['resultLimit'] && $this->config['resultLimit'] <= $this->itemCount) {
                    $items = array_slice($items, 0, $key + 1);
                    $shouldContinue = false;
                    break;
                }
            }

            $this->set($this->itemsPath, $results, $items);
        }

        return [$results, $shouldContinue];
    }

    /**
     * @param array $results
     * @param bool $shouldContinue
     * @return null
     */
    private function determineNextResultToken(array $results, $shouldContinue = true)
    {
        return $shouldContinue && $this->config['setNextResultTokenCondition']($results)
            ? $this->get($this->nextResultTokenPath, $results)
            : null;
    }

    /**
     * @param array $path
     * @param array $array
     * @return mixed
     */
    private function get(array $path, array $array)
    {
        $result = $array;

        foreach ($path as $key) {
            if (!isset($result[$key])) {
                return null;
            }

            $result = $result[$key];
        }

        return $result;
    }

    /**
     * @param array $path
     * @param array $array
     * @param mixed $value
     * @return null
     */
    private function set(array $path, array &$array, $value)
    {
        $temp = &$array;

        foreach ($path as $key) {
            $temp = &$temp[$key];
        }

        $temp = $value;
    }
}

redpajama_set_name: RedPajamaGithub


text:
Q: Color: rgba() workaround for Internet Explorer? I've been able to successfully use the following workaround method:
background: rgb(42,42,42);
background: rgba(42,42,42,0.7);

However, this only works with background:, and doesn't work with color:.
Does anyone know a workaround to get it to work with color: ?

A: Internet Explorer only accepts percentages as RGB values. This will work
color: rgb(16%,16%,16%);
color: rgba(42,42,42,0.7);

Microsoft Spec: http://msdn.microsoft.com/library/ms530749.aspx
DEMO: http://wecodesign.com/demos/stackoverflow-7082955.htm
UPDATE because of a bug in IE compatibility mode, if you declare two of the same thing, it ignores them both, the following will work in both compatibility mode and standards mode
h1 {
    color: rgb(16%,16%,16%);
}
h1 {
    color: rgba(42,42,42,0.7);
}

A: After some additional research I found that this did the trick:
<!--[if lte IE 8]>
    <style type="text/css">
        a#scrollUp {
            color: #ffffff !important;
        }
    </style>
<![endif]-->

It uses conditional stylesheets; lte IE 8 will match any IE version lower than or equal to 8. Just enter the proper (hex notation) color and prioritize it using important will work.
I hope this helps some other webdesigners as well!
I'm not sure about accepting my own answer, I just hope someone will still post a better (more efficient), working workaround.


Over the past decade, numerous studies have shown that many Americans have low vitamin D levels and as a result, vitamin D supplement use has climbed in recent years. Vitamin D has been shown to boost bone health and it may play a role in preventing diabetes, cancer, cardiovascular disease and other illnesses. In light of the increased use of vitamin D supplements, Mayo Clinic researchers set out to learn more about the health of those with high vitamin D levels. They found that toxic levels are actually rare.


On 9 April 1998, Ontario Northland Transportation Commission (the telecommunications operating division of which is now known as O.N. Tel) filed an application to delete discontinued items which are no longer available in the General Tariff.
The proposed tariff revisions to become effective on 9 May 1998 are approved.


text:
Apple Watch Ads Are Seductive
by Paul Grimsley | Apr 24, 2015
Apple Make Technology Sexy
OK, so I have said that smart watches don't really float my boat. Back when digital watches started to become a big thing (yes, I am old enough to remember that) I was a kid, and that kind of thing really got me whining at my parents for a new watch, but this "innovation" hit me as I felt there was a plateau in technology where the same ideas were just being reiterated on different sized screens. At some level portability and interconnectivity between things is sort of cool – I like the Internet Of Things as some techies have labelled it; smart objects that talk to each other and provide metrics about all aspects of your life that were beforehand unavailable as sources of accurate data. But I do get the feeling that some of the vibe here is like the constant format changes that were enforced on music and film collections, where you had to keep re-buying the same old thing continuously. Watch it on your watch, iPad, phone, laptop, desktop, whatever – it gets annoying.
Apples Adverts Tell A Story About Their Product
But I was sitting there watching the 3 new ads for the Apple Watch and something shifted in my universe – there was a degree of subtlety to those adverts that centers the watches in people's lives, and shows how people can use them to enhance their lives. You know what it is that you are watching, and you know what it is that you are being told about, but it isn't in your face. Apple have reached that kind of level where the aesthetic lets you know what and who you are dealing with. Sure, there has been a lot of buzz about this item beforehand, but I am sure that I could come to this advert without knowing anything about it and I would get that it was Apple. It does let you know at the end "The Watch Is Here", but by that point you already know.
It's not a bad looking piece of technology either – when has something from Apple ever looked ugly? I think this series of ads may have been the thing I needed though – an aesthetic communication from Apple that frames the product, rather than the bombastic circus that hypes any release from Apple as if it were the answer to the universal question. Apple is in seduction mode – they are not being loud and shouty, which is how some of the earlier press has seemed. I didn't want to buy one before – maybe now I might be a little bit closer to forking over my dollars.

redpajama_set_name: RedPajamaCommonCrawl


Affordable housing, while providing an invaluable service across the country, can prove challenging when tasked with the uniqueness of offering quality residences with limited resources. Keeping up with payroll, maintenance, inefficient utilities, overhead costs and various other tasks can cause property owners to struggle to provide an ideal community. With the right software however, properties can minimize and manage expenses while also saving time and money on operations. Here are five key areas to cut costs in affordable housing.
When utility systems are automated, property owners can easily manage rate changes and manage them with greater accuracy.
Automated processing ensures a keen eye is kept on utility usage, allowing for regulation of energy spikes and close monitoring of potential utility theft. Invoices can be expedited and fees can be collected more quickly, thus avoiding unnecessary shut-offs.
Get more efficiency from your maintenance staff with an integrated Mobile Facilities App. Maintenance apps allow staff to document repairs, update progress and send communications from the field. The property manager also stays informed of every step of the job with real-time visibility. The app can also simulate HUD REAC (Housing and Urban Development Real Estate Assessment Center) inspections and MOR (Management Occupancy Review) findings, letting property owners, managers and maintenance staff know the details of what needs to be fixed. More so, it will tell you when things need to be fixed to avoid costly surprises down the road.
With the right Spend Management Software, you can gain access to a list of approved vendors and products custom matched to your property. All vendors and products on the list provided would have online purchasing and invoicing capabilities to ensure property managers know where to buy and what to spend. In addition, this software can align your property with the right GPO (Group Purchasing Organization) to help save time and money, eliminating risk and maximizing purchasing power.
Mistakes in paperwork can be easy to achieve and costly to pay. A good resident-based document management system should enable you to upload all resident information to a secure database, providing an even deeper level of security than paper. These systems reduce and eliminate the need for paper, mail, file clerks, couriers, and paper storage. An efficient document management system not only adds data security and saves money from paper expenses, but also puts tenants in units faster by accelerating the approval process.
A revenue management system with an optimized pricing system can ensure properties achieve their ideal pricing and performance outcomes. Property owners are able to save time with effortless financial workflows and management fee calculation features.
Getting the most out of your housing community can be tricky, but with help from the right systems in place you can ensure your property is operating with the utmost efficiency.
To learn more about the Five Key Areas to Cut Costs and to review a checklist with your property in mind, download this free eBook now.


text:
Q: Firestore FieldValue.arrayUnion not working in a Cloud Function I try to use the arrayUnion functionality of Firestore to add items to an Array.
I have a web application and the code below works fine and the elements are added to MyArray :
firebase.firestore().collection("MyCollection").doc("MyDocument").update({
     MyArray: firebase.firestore.FieldValue.arrayUnion({element1: "qqq", element2: "www"})
});

But when I try to make it working in a cloud function, the code doesn't do anything. Nothing is written in my Firestore Array and there is no error on the cloud function logs.
Initialization :
const admin = require('firebase-admin');
admin.initializeApp();

My cloud function has an HTTP trigger that works fine. The code in the cloud function is :
admin.firestore().collection("MyCollection").doc("MyDocument").update({
     MyArray: admin.firestore.FieldValue.arrayUnion({element1: "qqq", element2: "www"})
});

The same code with a simple element added, in the same HTTP triggered cloud function works fine :
admin.firestore().collection("MyCollection").doc("MyDocument").update({
     element1: "qqq"
});

It seems that admin.firestore.FieldValue.arrayUnion doesn't do anything.
The complete cloud function is deployed fine :
exports.test = functions.https.onRequest((req, res) => {
   admin.firestore().collection("MyCollection").doc("MyDocument").update({

       MyArray: admin.firestore.FieldValue.arrayUnion({element1: "qqq", element2: "www"})

   });
   res.status(200).end();
});

He is my package.json file, all packages are up to date :
{
   "name": "functions",
   "description": "Cloud Functions for Firebase",
   "scripts": {
   "serve": "firebase serve --only functions",
   "shell": "firebase experimental:functions:shell",
   "start": "npm run shell",
   "deploy": "firebase deploy --only functions",
   "logs": "firebase functions:log"
},
"dependencies": {
   "@google-cloud/storage": "^1.7.0",
   "admin": "^1.4.0",
   "firebase": "^5.5.9",
   "firebase-admin": "^6.2.0",
   "firebase-functions": "^2.1.0",
   "firestore": "^1.1.6",
},
"private": true
}

Am I missing something ? Thanks a lot !

A: Thanks to Renaud and Doug, it works fine with a Promise :
exports.test = functions.https.onRequest((req, res) => {

return admin.firestore().collection("MyCollection").doc("MyDocument").update({

    MyArray: admin.firestore.FieldValue.arrayUnion({
        element1: "qqq",
        element2: "www"
    })

   }).then(() => {
    console.log('Write succeeded!');
    res.status(200).end();
   });

});

The function clean up was killing everything, and I did not thought that sending the status 200 was cleaning all the process. But one thing is strange : updating only one element is working fine without a promise, but updating the Array is not working ... This is certainly due to the execution time of a more complex process : the update of an Array...


text:
La terza divisione amministrativa della Costa Rica sono i distretti. La Costa Rica è costituita da 488 distretti, raggruppati in 82 cantoni, che costituiscono le 7 province.

Voci correlate
Province della Costa Rica
Cantoni della Costa Rica


text:
Candidate says 28 OSHA citations against family business are overzealous regulation
A candidate for lieutenant governor of California says many of the safety citations leveled against his family business are the product of overzealous regulators.
Abel Maldonado told Los Angeles Times these sorts of fines "put businesses out business." The newspaper included the statement in part of a profile of Maldonado.
Cal/OSHA has cited Maldonado's family farm, Agro-Jal Farming Enterprises, 28 times since 1990.
Four fines were in connection with the death of a worker in 2007 who was crushed by a tractor. The fines associated with an investigation of the death totaled $930. A federal report recently criticized California for failing to defend its investigators' findings during the appeals process, leading to excessive reductions in fines.
In separate incidents, the business was also cited four times for running tractors across fields with no driver at the wheel and no means of steering or stopping them.
The farm was also fined for failing to provide adequate access to shade or water for employees.
Maldonado casts himself as a defender of small businesses. He grew up on farms, picking strawberries with his parents and helping to grow the family business which now covers 6,000 acres and has 250 employees.
He's running for the seat Gov. Arnold Schwarzenegger appointed him to this year.
Maldonado still collects a six-figure salary as a controller for the farming company.
A Cal/OSHA spokesman said Agro-Jal's record with the agency is not extreme. The spokesman called it "average, or a little better."
Cal/OSHA is one of seven government agencies that have taken action against the farm. Liens have been filed against it nine times since 1992 for back taxes.
Do you agree or disagree with Maldonado's statement that OSHA is driving companies out of business? Let us know in the Comments Box below.


text:
Freshkills Park hosts Grasslands-themed dinner and discussion
Photo: Jo Cavallo
On June 25, Freshkills Park staff and local Staten Island residents came together at the Greenbelt Nature Center to participate in the first ever "Grasslands Dinner." The evening centered on the history of grasslands in the United States, the biodiversity of plants and animals associated with these habitats, and how Freshkills Park is helping to bring grassland back to New York City. The discussion was held over a delicious vegetarian meal from Dig Inn, a restaurant that sources ingredients from their own Dig Farm in Chester, NY, as well as from other small-scale local farms.
As guests arrived to the Nature Center, they were greeted with a soundscape of grassland noises featuring recordings of sparrow songs and insect chirpings taken from Freshkills Park. Tables were set with bundles of a diverse array of freshly cut and labeled grassland plants. A series of "icebreaker" questions spread out among the tables asked the guests to think about what their favorite habitats were and how they would describe the experience of being in a grassland, while booklets for the guests to take home offered some introductory information about the scientific and social history of grasslands in the United States.
Laura Truettner, Manager for Park Development at Freshkills Park, began the discussion by delving into an explanation of where the evening's dinner came from, including information about the farms from which the ingredients were sourced, the history of farming and land use in the New York area in general, and how farming has changed in the United States over time. Cait Field, Manager for Science & Research Development at Freshkills, connected this information to grasslands by noting that the United States has less than 1% of its original tallgrass prairie remaining – more of a loss than any other habitat has experienced – mainly due to the development of grasslands into farmland.
The discussion then turned to grassland biodiversity. Terrance Caviness, Education Program Coordinator, talked about the grass species displayed around the tables in the room and about the grassland composition at Freshkills Park in particular. José Ramírez-Garofalo, a graduate student from the College of Staten Island who conducts research at Freshkills, noted different grassland birds that rely on this habitat to survive, and discussed how Freshkills' grasslands are having a big impact in allowing certain declining species like the grasshopper sparrow to return to and thrive in Staten Island. Guests connected this to their own experiences at the park, reflecting on species they were able to observe during their visits such as the American kestrel.
Finally, Field reviewed grassland management practices and the impact that they have on maintaining healthy, functioning habitat. Management largely depends on the specific site – what works for the wildlife at a large park like Freshkills may not work at a smaller site. Additionally, as climate change worsens, management practices may need to adjust to the varying conditions. However, there is a general lack of widespread knowledge on grassland habitats, and as a result, as Freshkills' grasslands continue to grow and develop, it will be important to see how the different plant and animal species they are home to will develop with them. Ongoing projects such as grassland monitoring, bird banding, and grassland bird monitoring are helping to ensure that researchers can monitor the health of the habitat, track any changes that are occurring, and learn as much as possible about these fascinating environments.
Thank you to everyone who came out for this event! For more information on upcoming events like this, join the newsletter and follow @freshkillspark on Instagram, Twitter, and Facebook.
Tags: conservation, environmental education, farm, grasslands, habitat, land use, programs, research, Thats So Native
« North Park Construction Continues with Foundations for Signature Structures
Highlights from the June 30th Open Hours Event »


Situated at the rear of the block, this single storey unit offers 3 bedrooms all with robes and master with full ensuite. Kitchen meals area with blend of quality ceramic tiling and polished floors. Double lock up garage, private rear courtyard and landscaped gardens including water tank.


text:
Secure Messaging Gets the Green Light in Healthcare
K Royal | May 5, 2016
In a cascading pattern of modernization, the U.S. federal government and healthcare accreditation bodies are building in guidelines for secure messaging. The most recent Certification Companion Guide (CCG) issued by the Office of the National Coordinator includes guidance on secure messaging between providers and patients.
Specifically, the criteria that need to be met include separate testing for a "trusted connection" either on a message level or a transport level and apply only to the content of a message, not the user's device. Examples of secure messaging include email, portal, and texting, but any method must be bidirectional. On a more technical note, the CCG states that only encryption and hashing algorithms are in scope, not random number generators.
On a much more recent note, the Joint Commission (formerly the Joint Commission on Accreditation of Healthcare Organizations) stated in its May newsletter that it has ended its 2011 ban on texting medical orders.
It was only five years ago that the technology could not adequately address the concerns of the Joint Commission, namely securing the message, verifying the identity of the users, and capturing the message in the medical record. At this time, the Joint Commission has revised its position on the prohibition of texting medical orders as long as certain criteria is met. These criteria are for messaging platforms are:
Secure sign-on process
Encrypted messaging
Delivery and read receipts
Date and time stamp
Customized message retention time frames, and
Specified contact list for individuals authorized to receive and record orders
Additionally, organizations must consider how text messages will be captured in the patients' medical records. The Joint Commission suggests that its requirements for verbal orders could be adapted for text orders. Further, while the Joint Commission staff prepares more details around texting medical orders, the Joint Commission recommends that healthcare organizations prepare their environments and procedures to address this capability. Such actions should include a risk assessment, policies around when texting is acceptable, determine the use case and load, and conduct training for providers and staff.
About K Royal
K Royal is the Vice President, Assistant General Counsel and serves as the Privacy Officer for CellTrust. An attorney and compliance professional with 20 years of experience in the legal and health-related fields, she brings a thorough perspective in global program implementation. Skilled in privacy law, breach management, compliance and program development, Ms. Royal was recently honored as the ACC's 2015 Robert I. Townsend, Jr. Member of the Year.


text:
require 'spec_helper'

module Fountain::EventStore
  describe MemoryEventStore do

    let(:stream_type) { 'Test' }
    let(:stream_id) { SecureRandom.uuid }

    describe '#load_slice' do
      it 'raises an error on non-existent stream' do
        expect {
          subject.load_slice(stream_type, stream_id, 10)
        }.to raise_error(StreamNotFoundError)
      end

      it 'returns a partial stream starting at the given version' do
        subject.append(stream_type, stream_id, build_stream(10))
        expect(subject.load_slice(stream_type, stream_id, 5).size).to eql(5)
      end

      it 'returns a partial stream starting and ending at the given versions' do
        subject.append(stream_type, stream_id, build_stream(10))

        expect(subject.load_slice(stream_type, stream_id, 5, 6).size).to eql(2)
        expect(subject.load_slice(stream_type, stream_id, 5, 100).size).to eql(5)
      end
    end

    describe '#load_all' do
      it 'raises an error on non-existent stream' do
        expect {
          subject.load_all(stream_type, stream_id)
        }.to raise_error(StreamNotFoundError)
      end

      it 'returns the entire event stream' do
        subject.append(stream_type, stream_id, build_stream(10))
        expect(subject.load_all(stream_type, stream_id).size).to eql(10)
      end
    end

    describe '#append' do
      it 'raises an error on duplicate sequence numbers' do
        subject.append(stream_type, stream_id, build_stream(2))
        subject.append(stream_type, stream_id, build_stream(2, 2))
        expect {
          subject.append(stream_type, stream_id, build_stream(2, 2))
        }.to raise_error
      end
    end

    def build_stream(size, offset = 0)
      size.times.map do |sequence_number|
        Fountain::Domain::EventEnvelope.build do |builder|
          builder.payload = Object.new
          builder.sequence_number = sequence_number + offset
        end
      end
    end

  end
end


text:
The Last Christian
Fr. James V. Schall
Nietzsche's aphorism, "The Last Christian died on the Cross," has several interpretations. It is a cry of disappointment: The Christians who followed Christ did not live up to His example. Nietzsche was broken-hearted, even scandalized, by the failure of Christians to live as they ought. He wanted to be like the One who died on the cross. So, in this background, we write off historical Christians as a degenerate, gutless outfit lacking courage to follow their Master.
The next step, no doubt, is to figure out some other way to live, since our disappointment is so great. This "scandal" justifies a whole new theory: We have to be courageous. We have to be noble. We make our own morals. We are not "new men" but supermen, unflinching before the sick example of existing Christians. We are beyond good and evil; we define them. Yet Nietzsche's new theory did not give him what he wanted, either. He was even disappointed in his own theories, a not uncommon experience.
Of course, if Christ ever expected His followers to be sinless just like Himself, He would have had a different theology from the one that He gave us. The very fact that He died to redeem us, and that we could have our sins forgiven, means that He did not expect that everyone would be, just like Himself, sinless. If a human being were sinless, he too would have had to be divine like Christ Himself. Implicitly, Nietzsche's aphorism is itself a divine claim. The Christian who died on the cross was the Son of God, the Word made flesh. If He were not, we would still be in our sins.
In the reading for the Monday of Holy Week, St. Augustine writes: "The apostle Paul saw Christ, and extolled his claim to glory. He had many great and inspired things to say about Christ, but he did not say that he boasted in Christ's wonderful works: in creating the world, since he was God with the Father, or in ruling the world, though he was also a man like us. Rather, he said: Let us not boast except in the cross of our Lord Jesus Christ." Here, in the words of Paul through Augustine, we have the cross of Christ again.
What does Paul mean telling us that we are to "boast" in the cross of Christ? Augustine spells it out. We could easily and impressively say, "Look, our God created the world." That would be true. We could give some reasons why this might be so. Or we might say, "Look, Christ could have been a political ruler." After all, this is what many Jews anticipated the Messiah to be. If we recall the temptations in the desert, this world-rule is the deal that Satan offered Christ. The only thing He had to do was to fall down and adore the devil, who really was testing this figure to see who He was.
When Paul affirms that we are to boast in the cross, he is, I think, telling us that the way the Father did choose to redeem us was best for everyone concerned, particularly for ourselves. But this way involves the problem of the crucifixion, by no means a pleasant affair. Indeed, it was about the worst form of death anyone could suffer, not only because of its pain but because of its utter humiliation before other men.
The crucifixion has overtones among the Greeks. Sophocles said that, "Man learns by suffering." Christ did not suffer just because He liked to try it out. The purpose of the Incarnation was the redemption of our sins, the ongoing ones Nietzsche could not quite figure out. God did not — or better, He could not — redeem us without our own free participation.
The crucifixion, in this sense, is an invitation to look at the consequences of our sins. Moreover, we are not looking at the Man suffering as if He were there justly. Pilate's washing of his hands, however unmanly, did acknowledge that no guilt was in this Man.
Redemption is an invitation, not something forced on us. This invitation is all it could be if we are to freely accept the final destiny offered to us, that of living the life of the Trinity after the manner of the Son who died for us.
The "last" Christian was the Word made flesh who dwelt amongst us. This crucifixion is what happened to Him by our free agency. On seeing this result, unlike Nietzsche, we do not run off and found our own theory of true "being." True reality is there before us.
Our response remains that of the Good Thief: "Lord, be merciful to me, a sinner." The Good Thief saw what Nietzsche did not, though he suspected it. The better path than the one we make for ourselves is already there. This is what our redemption is about.
Tagged as Good Thief Lord, Holy Week, Lord Jesus Christ, Yet Nietzsche
By Fr. James V. Schall
The Rev. James V. Schall, SJ, (1928-2019) taught government at the University of San Francisco and Georgetown University until his retirement in 2012. Besides being a regular Crisis columnist since 1983, Fr. Schall wrote nearly 50 books and countless articles for magazines and newspapers.


I was looking for some numbers on e-book sales per device and store, and found this article on Publisher's Weekly.
That's just for the US, though. I expect B&N was non-existent anywhere else in 2012 – it only just started expanding into Europe at the end of the year. Kobo probably takes B&N's place in other markets.
I wonder what are the most popular "other" people use?
"50% of the respondents to a Diesel survey reported that they use dedicated e-readers, 20% use a personal computer, and 16% use tablets, but the tablet component is growing." So that's only 20% PC purchases. I presume most of them are still using branded bookstores instead of author websites. That doesn't bode well for the author-vendor model.
A certain well-known self-published author had recently requested me to present a brief tutorial on how I format my e-books.


Containment Protocols: Site A82 has been constructed directly above RPC-701, with the express purpose of cataloging as much data about the RPC-701 cave system as possible before further erosion events render the information it contains inaccessible, and to prevent the adverse effects of local mining operations on its stability. Observation and exploration of RPC-701 is to be performed by untethered, small-scale remote drones, to avoid causing further damage to the structures of the object.
Description: RPC-701 is the remains of a colony of naturally-occurring nuclear reactors which, for a brief period during the Paleoproterozoic era (approx. 1700Ma), gained sapience and later became extinct. The RPC-701 cave system is located ███m below the surface in ████, Gabon, and is accessible via a closed branch of the ████ uranium mine. Though the full extent of the cave system has not been mapped due to its structural fragility, radar imaging reveals that it is approximately 20 km3 in volume and comprises at least 31 instances of RPC-701-1. The caves are currently filled with fresh groundwater, inhabited by colonies of cyanobacteria which appear to be descendants of RPC-701-3.
RPC-701-1 refers to the fluidic/biological nuclear intelligences which inhabited RPC-701. Composed of extremely fine lattices of highly compacted uranium-235, designated RPC-701-2, inhabited by colonies of radiation-resistant RPC-701-3 extremophile cyanobacteria, RPC-701-1 apparently achieved some form of computing intelligence, derived from the movement of water through the 235U matrices via convection currents and the motion of RPC-701-3 colonies. RPC-701-1 instances, referred to in their own language as "Warmth Occupying Volume", were aware of the presence of other instances through the effects their presence had on ambient heat and water currents, and developed a "spoken" language based on current pressure and temperature regulation.
RPC-701-1's only way of physically interacting with the cave was the use of continuous current to slowly wear regular patterns in stone, a means by which they encoded their knowledge. The vast majority of RPC-701-1 interactions recorded in RPC-701 appear to have been analogous to philosophical dialogues, or discussions on the nature of RPC-701-1 society. The written language of RPC-701-1 was initially considered untranslatable, until the discovery of RPC-701-1-INS-1, a section of writing which appears to be a derivation of the mathematical patterns underlying the RPC-701-1 language, beginning with a simple definition of their base-16 number system and working its way up to more abstract concepts. While this has made comprehension of the language possible, researchers are reminded that all RPC-701-1 translations are at best simple closest-fit approximations to complex mathematical symbols and relationships, and cannot be considered totally reliable. Many of the original records appear to have been destroyed over time via friction and erosion from the cyanobacteria colonies.
What follows is an approximate translation of a fragmentary discussion between RPC-701-1-3 ("Colder-than-others") and RPC-701-1-4 ("Rushes-Downwards-To-Stillness"). The tone and language of the discussion is typical of other RPC-701-1 dialogues. Comparative wear patterns reveal that the dialogue was recorded over a period of nearly 500 years, giving some idea of the relative timescale of RPC-701-1 intelligence.
Colder-than-others: You claim that you do not know that I exist. How is this so? Do I not communicate with you? Do my currents not co-mingle with your [warmth/mind/body], that my thoughts might become yours?
Rushes-Downwards-to-Stillness: You interact with my [warmth/mind/body], but how can I be sure that you exist? I sense you, but the turbulence and flow and heat are distinct from my thoughts. In my sense, I can be certain of your existence, but I cannot be certain in my thoughts that you are present.
C: Does not your [warmth/mind/body] come to know me through your mind? Surely, to sense me is to be aware of my existence. It would seem to me that, in your [thoughts? thinking?], you would regard the entire world as being [bubbles? Air-pockets?] of nonexistence, a mere [air-pocket, probably illusion or dream] of your own [warmth/mind/body].
R: Precisely. My senses tell me that I exist, along with you and all the other [Heat], be they [close, lit. strong flow of current] or [far, lit. weak flow of current], surrounded by the water, which is bound by the slowly-destroyable universe. However, in the same way that I can [touch/speak] you a cold current when my true meaning is warm, so too can my senses and [warmth/mind/body] deceive my thoughts.
C: I understand. It seems to me that your thesis is remarkably [non-flowing?]. You give credit only to your own thoughts, and deny the truth of the [warmth/mind/body] of yourself and others.
R: The only truth I truly know is that my thoughts are.
Later RPC-701-1 records indicate that their society began to collapse as RPC-701-2 structures became more efficient and intricate over time. Computer simulations based off the remains of RPC-701-1 indicate that, after a certain level of lattice complexity, the motion of fluid through RPC-701-2 would induce destructive sympathetic oscillations, leading to the eventual collapse of any RPC-701-1 configuration beyond a certain level of intelligence. Dialogues and records from the later period of RPC-701 habitation take on an increasingly negative and nihilistic tone, apparently as RPC-701-1 instances began to fail, with increasing reference to a word which approximates the concept of entropy/air-pocket, or the slow decay towards non-existence.