Common Lisp Sampling in Parallel - lisp

Assume that I want to draw samples from some probability distribution. In the case below I draw some uniformly distributed rv's between 0 and 1 for 10000 times. I do not care about the ordering of the random samples in the vector, after all they are random.
(setf my-vec (make-sequence 'vector 10000 :initial-element 0))
(loop :for i :from 0 :to 9999 :do
(setf (svref my-vec i) (random 1.0)))
I have a multicore machine and I want to implement the above code in parallel. (i.e. assuming I have 4 cores, sampling 2500 in one core and at the end appending all samples in to one single vector. I have asked before about Common Lisp Parallel Programming
here. Assuming that I am a total newbie in CL and programming in general what should be my approach to this problem? I do not require advanced characteristics in parallelization, I just want to distribute the computational load of the sampling to machine cores equally. If you can point out some steps to do for parallelization or some online tutorial stuff that I can benefit from that would be really nice. Thanks a lot in advance.

You need a Common Lisp implementation which is multi-core capable. Examples are CCL, LispWorks and on some platforms (IIRC) SBCL.
A simple example using LispWorks 6.1 and its multiprocessing capabilities follows.
It uses a construct called a barrier. Processes wait on a barrier until enough processes arrive. Here it means that enough threads have finished their vector initialization.
The typical function to start a thread is PROCESS-RUN-FUNCTION.
(defun make-random-vector (&key (size 10000) (n-threads 4))
(let ((vector (make-sequence 'vector size :initial-element 0))
(barrier (mp:make-barrier (1+ n-threads)))
(delta (truncate size n-threads)))
(loop for i below n-threads
do (mp:process-run-function
"init"
nil
(lambda (barrier vector start end)
(loop for i from start below end do
(setf (svref vector i) (random 1.0)))
(mp:barrier-wait barrier :pass-through t))
barrier
vector
(* i delta)
(+ delta (* i delta))))
(mp:barrier-wait barrier)
vector))

Related

Why are the number of bytes consed reported by TIME differing for different calls?

Using SBCL 1.4.12, I am looking at Exercise 17.9 from Stuart Shapiro's Common Lisp: An Interactive Approach, and timing a reverse function applied to a list of 10,000 elements. When I time this function using the same list, the time function reports a different number of bytes consed each time.
Here is the code for the reverse function:
(defun reverse2 (l1 l2)
"Returns a list consisting of the members of L1 in reverse order
followed by the members of L2 in original order."
(check-type l1 list)
(check-type l2 list)
(if (endp l1) l2
(reverse2 (rest l1)
(cons (first l1) l2))))
(defun reverse1 (l)
"Returns a copy of the list L1
with the order of members reversed."
(check-type l list)
(reverse2 l '()))
I generated the list in the REPL with:
(defvar *test-list* '())
(dotimes (x 10000)
(setf *test-list* (cons x *test-list*)))
Here are the results of four test-runs:
CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
520,386 processor cycles
145,696 bytes consed
CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
260,640 processor cycles
178,416 bytes consed
CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
279,822 processor cycles
178,416 bytes consed
CL-USER> (time (ch17:reverse1 *test-list*))
Evaluation took:
0.000 seconds of real time
0.000000 seconds of total run time (0.000000 user, 0.000000 system)
100.00% CPU
264,700 processor cycles
161,504 bytes consed
The second and third test runs (which were several minutes apart) show the same number of bytes consed, but the other two show different numbers. I expected the timing to vary, but I did not expect the number of bytes consed to vary. I see that the HyperSpec says of the time function that:
In general, these timings are not guaranteed to be reliable enough for
marketing comparisons. Their value is primarily heuristic, for tuning
purposes.
But I expected that this applies to timings, not to byte counts. Are the bytes consed values reported by time unreliable? Is there an optimization behind the scenes that is responsible for this? What am I missing?
The amount of consing (in the 'bytes of memory allocated' sense) depends on everything:
it depends on how many objects of what types you allocate;
it depends on fine implementation details of the allocator such as whether it allocates in large chunks and whether 'allocation' between the allocating of large chunks is recorded;
it depends on the garbage collector -- was one triggered? if so what sort of one? how hairy is the GC? does the GC itself allocate? how is allocation counted across GCs?
it depends on whether the system is doing other allocation, for instance in other threads, and whether that allocation gets counted or not in your thread -- is there just one allocator or are there per-thread allocators?
it depends on the phase of the Moon & whether Pluto is a planet;
and so on.
In general, if you have a very simple single-threaded implementation with a very simple allocator and a very simple GC then keeping track of allocation is easy and you will get reliable numbers. Many Lisp implementations were once like that: they were easy to understand and you got to drink a lot of tea while they did anything (OK, machines were slower then, but still they were often impressively slow even by the standards of the time). Now Lisps have multiple threads, sophisticated allocators and GCs and they're really fast, but how much allocation happens has become a question which is very hard to answer and often slightly unpredictable.

Lisp interactive emacs multiplying incorrectly

I'm running the following code on Emacs Lisp Interaction:
(defun square (x) (* x x))
(square (square (square 1001)))
which is giving me 1114476179152563777. However, the ((1001^2)^2)^2 is actually 1008028056070056028008001.
How is this possible?
#Barmar's answer is accurate for Emacs versions < 27.
In Emacs 27 bignum support has been added. NEWS says:
** Emacs Lisp integers can now be of arbitrary size.
Emacs uses the GNU Multiple Precision (GMP) library to support
integers whose size is too large to support natively. The integers
supported natively are known as "fixnums", while the larger ones are
"bignums". The new predicates 'bignump' and 'fixnump' can be used to
distinguish between these two types of integers.
All the arithmetic, comparison, and logical (a.k.a. "bitwise")
operations where bignums make sense now support both fixnums and
bignums. However, note that unlike fixnums, bignums will not compare
equal with 'eq', you must use 'eql' instead. (Numerical comparison
with '=' works on both, of course.)
Since large bignums consume a lot of memory, Emacs limits the size of
the largest bignum a Lisp program is allowed to create. The
nonnegative value of the new variable 'integer-width' specifies the
maximum number of bits allowed in a bignum. Emacs signals an integer
overflow error if this limit is exceeded.
Several primitive functions formerly returned floats or lists of
integers to represent integers that did not fit into fixnums. These
functions now simply return integers instead. Affected functions
include functions like 'encode-char' that compute code-points, functions
like 'file-attributes' that compute file sizes and other attributes,
functions like 'process-id' that compute process IDs, and functions like
'user-uid' and 'group-gid' that compute user and group IDs.
and indeed using my 27.0.50 build:
(defun square (x) (* x x))
square
(square (square (square 1001)))
1008028056070056028008001
Emacs Lisp doesn't implement bignums, it uses the machine's integer type. The range of integers it supports is between most-negative-fixnum and most-positive-fixnum. On a 64-bit system, most-positive-fixnum will be 261-1, which has about 20 decimal digits.
See Integer Basics in the Elisp manual.
The correct result of your calculation is 25 digits, which is much larger than this. The calculation overflows and wraps around. It should be correct modulo 262.
You could use floating point instead. It has a much larger range, although very large numbers lose precision.
(square (square (square 1001.0)))
1.008028056070056e+24

Emacs lisp - extract number under point between two brackets

I'm pretty new to Emacs Lisp and still learning how to do some of the basics.
I have some text like [123] and I want to extract the number 123. I've goofed around with a few different attempts but I still can't seem to capture the number reliably. The closest I've gotten is extracting the character ].
Can anyone point me in a direction? My biggest struggle is in understanding how to capture the number once I've used search-forwards and search-backwards to capture the point positions of the brackets.
Thanks in advance!
Try
(when (re-search-forward "\\[\\([0-9]+\\)\\]" nil t)
(string-to-number (match-string 1)))
Alternatively, when the point is already on top of the number, thing-at-point may be more convenient:
(string-to-number (thing-at-point 'sexp))

CLISP overflow after multiplication

i'm trying to get a first lisp program to work using the CLISP implementation, by typing
(print (mod (+ (* 28433 (expt 2 7830457) 1)) (expt 10 10))))
in the REPL.
but it gives me *** - overflow during multiplication of large numbers. i thought lisp features arbitrary size/precision. how could that ever happen then?
Lisp's bignums may hold really large numbers, but they too have their limits.
In your case, you can combine exponentiation and modulus into a single procedure, e.g. as in http://en.wikipedia.org/wiki/Modular_exponentiation#Right-to-left_binary_method.
According to http://clisp.cons.org/impnotes/num-concepts.html the maximum size for a bignum is (2^2097088 - 1) and your 2^7830457 is much larger than that.
Perhaps you can look at breaking down that number - perhaps separate out a number of smaller 2^X factors...
Chances are there's a better way to solve the problem. I haven't made it that far on PE, but I know the few that I've done so far tend to have "aha!" solutions to problems that seem out of a computer programs range.
This one especially - 2^7830457 is a huge number -- try (format t "~r" (expt 2 160)). You might try to look at the problem in a new light and see if there's a way to look at it that you haven't thought of.
Lisp is a family of languages with dozens of dialects and hundreds of different implementations.
Computers have finite memory. Programs under some operating systems may have limitations about the memory size. Different Common Lisp implementations use different numeric libraries.
You may want to consult your CLISP manual for its limitations of its various data types.
CLisp provided the function "mod-expt" (or EXT:mod-expt)
[1]> (mod-expt 2 1000000 59)
53
which is pretty fast. And for your purpose that works.

The subsets-sum problem and the solvability of NP-complete problems

I was reading about the subset-sums problem when I came up with what appears to be a general-purpose algorithm for solving it:
(defun subset-contains-sum (set sum)
(let ((subsets) (new-subset) (new-sum))
(dolist (element set)
(dolist (subset-sum subsets)
(setf new-subset (cons element (car subset-sum)))
(setf new-sum (+ element (cdr subset-sum)))
(if (= new-sum sum)
(return-from subset-contains-sum new-subset))
(setf subsets (cons (cons new-subset new-sum) subsets)))
(setf subsets (cons (cons element element) subsets)))))
"set" is a list not containing duplicates and "sum" is the sum to search subsets for. "subsets" is a list of cons cells where the "car" is a subset list and the "cdr" is the sum of that subset. New subsets are created from old ones in O(1) time by just cons'ing the element to the front.
I am not sure what the runtime complexity of it is, but appears that with each element "sum" grows by, the size of "subsets" doubles, plus one, so it appears to me to at least be quadratic.
I am posting this because my impression before was that NP-complete problems tend to be intractable and that the best one can usually hope for is a heuristic, but this appears to be a general-purpose solution that will, assuming you have the CPU cycles, always give you the correct answer. How many other NP-complete problems can be solved like this one?
NP-complete problems are solvable, just not in polynomial time (as far as we know). That is, an NP-complete problem may have an O(n*2^n) algorithm that could solve it, but it won't have, for example, an O(n^3) algorithm to solve it.
Interestingly, if a quick (polynomial) algorithm was found for any NP-complete problem, then every problem in NP could be solved in polynomial time. This is what P=NP is about.
If I understand your algorithm correctly (and this is based more on your comments than on the code), then it is equivalent to the O(n*2^n) algorithm here. There are 2^n subsets, and since you also need to sum each subset, the algorithm is O(n*2^n).
One more thing about complexity - the O(whatever) only indicates how well a particular algorithm scales. You cannot compare two algorithms and say that one is faster than the other based on this. Big-O notation doesn't care about implementation details and optimisations - it is possible to write two implementations of the same algorithm with one being much faster than the other, even though they might both be O(n^2). One woman making babies is an O(n) operation, but the chances are that this is going to take a lot longer than most O(n*log(n)) sorts you perform. All you can say based on this is that sorting will be slower for very large values on n.
All of the NP-complete problems have solutions. As long as you're willing to spend the time to compute the answer, that is. Just because there's not an efficient algorithm, doesn't mean there isn't one. For example, you could just iterate over every potential solution, and you'll eventually get one. These problems are used all over the place in real-world computing. You just need to be careful about how a big a problem you set for yourself if you're going to need exponential time (or worse!) to solve it.
I am not sure what the runtime
complexity of it is, but appears that
with each element "sum" grows by, the
size of "subsets" doubles, plus one,
so it appears to me to at least be
quadratic.
If the run-time doubles for each increase in N, you're looking at an O(2^N) algorithm. That's also what I'd expect from visiting all subsets of a set (or all members of the powerset of a set), as that's exactly 2^N members (if you include rhe empty set).
The fact that adding or not adding an element to all hitherto-seen sets is fast doesn't mean that the total processing is fast.
What is going on here could be expressed much more simply using recursion:
(defun subset-sum (set sum &optional subset)
(when set
(destructuring-bind (head . tail) set
(or (and (= head sum) (cons head subset))
(subset-sum tail sum subset)
(subset-sum tail (- sum head) (cons head subset))))))
The two recursive calls at the end clearly show we are traversing a binary tree of depth n, the size of the given set. The number of nodes in the binary tree is O(2^n), as expected.
It's karpreducible to polynomial time. Reduce with Karp reduction to a decision problem O(nM) using a heap or binary search upper bounds is log(M*2^M)=logM+log(2^M)=logM+Mlog2 Ergo Time:O(nM)