Skip to content

Commit

Permalink
Work around out of memory issue with foreign allocator. (#199)
Browse files Browse the repository at this point in the history
* Work around out of memory issue with foreign allocator.

* Use TRIVIAL-GARBAGE.

* Add comment.

* Trigger garbage collection only when using foreign memory allocation.

* Be explicit about the transient nature of the current fix.
  • Loading branch information
jmbr authored and Robert Smith committed Oct 28, 2019
1 parent 1b3714f commit 5fd4492
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
29 changes: 16 additions & 13 deletions app/src/entry-point.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -328,18 +328,17 @@ Copyright (c) 2016-2019 Rigetti Computing.~2%")
(terpri)))

(defun allocation-description-maker (kind)
"Return a function INTEGER -> ALLOCATION that takes a number of elements and returns a proper descriptor for the allocation."
(cond
((string-equal kind "native")
(lambda (length)
(make-instance 'qvm:lisp-allocation :length length)))
((string-equal kind "foreign")
(lambda (length)
(make-instance 'qvm:c-allocation :length length)))
(t
(error "Invalid kind of allocation ~S, wanted any of {~{~S~^, ~}"
kind
*available-allocation-kinds*))))
"Return a function INTEGER -> ALLOCATION that takes a number of elements and returns a proper descriptor for the allocation. In addition to said function, return the allocator description used."
(let ((x (assoc kind *allocation-descriptions* :test #'string=)))
(if x
(let ((description (cdr x)))
(values
(lambda (length)
(make-instance description :length length))
description))
(error "Invalid kind of allocation ~S, wanted any of {~{~S~^, ~}"
kind
*available-allocation-kinds*))))

(defun log-level-string-to-symbol (log-level)
(let ((log-level-kw (assoc (intern (string-upcase log-level) 'keyword)
Expand Down Expand Up @@ -415,7 +414,11 @@ Version ~A is available from https://www.rigetti.com/forest~%"
(setf qvm:*transition-verbose* t))

(when default-allocation
(setq **default-allocation** (allocation-description-maker default-allocation)))

(multiple-value-bind (allocation description)
(allocation-description-maker default-allocation)
(setf **default-allocation** allocation
*allocation-description* description)))

(when (plusp time-limit)
(setf *time-limit* (/ time-limit 1000.0d0)))
Expand Down
8 changes: 7 additions & 1 deletion app/src/globals.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
(global-vars:define-global-var **persistent-wavefunction** nil)
(global-vars:define-global-var **persistent-wavefunction-finalizer** (constantly nil))

(defparameter *allocation-descriptions* '(("native" . qvm:lisp-allocation)
("foreign" . qvm:c-allocation))
"Association list of allocation descriptions.")

(defvar *allocation-description* 'qvm:lisp-allocation "Default allocation description.")

(global-vars:define-global-var **default-allocation**
(lambda (n) (make-instance 'qvm:lisp-allocation :length n)))
(lambda (n) (make-instance *allocation-description* :length n)))

(deftype simulation-method ()
"Available QVM simulation methods."
Expand Down
12 changes: 11 additions & 1 deletion app/src/handle-request.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,14 @@ The mapping vector V specifies that the qubit as specified in the program V[i] h
:measurement-noise measurement-noise)
(load-time-value
(with-output-to-string (s)
(yason:encode t s)))))))))
(yason:encode t s))))))))

(when (eq *allocation-description* 'qvm:c-allocation)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Trigger the garbage collector to ensure that foreign memory is freed
;; (see issue #198).
;;
;; TODO: This is a temporary fix and is not 100% satisfactory because it
;; potentially stops all threads for GC after each request.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(tg:gc :full t)))

0 comments on commit 5fd4492

Please sign in to comment.