The context class of GPU linear algorithm and GPU memory management.
Parameters:
-
gpu_device
(int, default:
0
)
–
-
memory_limit
(int, default:
None
)
–
the limitation of memory pool. Unit is GiB
Examples:
with CalculationLayer(gpu_device=0, memory_limit=4) as CL:
gpu_A = cp.array(cpu_A)
gpu_B = cp.array(cpu_B)
result = CL.dot(gpu_A, gpu_B, gpu_out=True)
Source code in QuICT/ops/utils/calculation_layer.py
| def __init__(self, gpu_device: int = 0, memory_limit: int = None):
if gpu_device != cp.cuda.runtime.getDevice() and gpu_device < cp.cuda.runtime.getDeviceCount():
dev = cp.cuda.Device(gpu_device)
cp.cuda.Device.use(dev)
self.mempool = cp.get_default_memory_pool()
self.pinned_mempool = cp.get_default_pinned_memory_pool()
if memory_limit:
self.mempool.set_limit(memory_limit * 1024 ** 3)
# Set Memory allocator
cp.cuda.set_allocator(self.mempool.malloc)
# Memory Record
self.mempool_used = []
|
MatrixPermutation
MatrixPermutation(A, mapping, changeInput: bool = False, gpu_out: bool = True, sync: bool = True)
permute mat with mapping, inplace
Parameters:
-
A(np.array<np.complex>)
–
-
mapping(np.array<int>)
–
-
changeInput(bool)
–
-
gpu_out(bool)
–
Source code in QuICT/ops/utils/calculation_layer.py
| def MatrixPermutation(
self,
A,
mapping,
changeInput: bool = False,
gpu_out: bool = True,
sync: bool = True
):
""" permute mat with mapping, inplace
Args:
A(np.array<np.complex>): the matrix A.
mapping(np.array<int>): the qubit mapping.
changeInput(bool): whether changes in A.
gpu_out(bool): return result from GPU.
"""
gpu_A = self._var_normalized(A)
result = GPUCalculator.MatrixPermutation(gpu_A, mapping, changeInput, gpu_out, sync)
return self._result_normalized(result, gpu_out)
|
MatrixTensorI
MatrixTensorI(A, n, m, gpu_out: bool = True, sync: bool = True)
tensor I^n and A and I^m
Parameters:
-
A(np.array<np.complex>)
–
-
n(int)
–
-
m(int)
–
-
gpu_out(bool)
–
return result from GPU into CPU
Returns:
-
–
np.array: the tensor result I^n ⊗ A ⊗ I^m
Source code in QuICT/ops/utils/calculation_layer.py
| def MatrixTensorI(self, A, n, m, gpu_out: bool = True, sync: bool = True):
""" tensor I^n and A and I^m
Args:
A(np.array<np.complex>): the matrix A
n(int): the index of indentity
m(int): the index of indentity
gpu_out(bool): return result from GPU into CPU
Returns:
np.array<np.complex>: the tensor result I^n ⊗ A ⊗ I^m
"""
gpu_A = self._var_normalized(A)
result = GPUCalculator.MatrixTensorI(gpu_A, n, m, gpu_out, sync)
return self._result_normalized(result, gpu_out)
|
VectorPermutation
VectorPermutation(A, mapping, changeInput: bool = False, gpu_out: bool = True, sync: bool = True)
permutaion A with mapping, inplace
Parameters:
-
A(np.array<np.complex>)
–
-
mapping(np.array<int>)
–
-
changeInput(bool)
–
-
gpu_out(bool)
–
Returns:
-
–
np.array: the result of Permutation
Source code in QuICT/ops/utils/calculation_layer.py
| def VectorPermutation(
self,
A,
mapping,
changeInput: bool = False,
gpu_out: bool = True,
sync: bool = True
):
""" permutaion A with mapping, inplace
Args:
A(np.array<np.complex>): the matrix A.
mapping(np.array<int>): the qubit mapping.
changeInput(bool): whether changes in A.
gpu_out(bool): return result from GPU.
Returns:
np.array<np.complex>: the result of Permutation
"""
gpu_A = self._var_normalized(A)
result = GPUCalculator.VectorPermutation(gpu_A, mapping, changeInput, gpu_out, sync)
return self._result_normalized(result, gpu_out)
|
clear_memory
released unused memory in current memory pool.
Source code in QuICT/ops/utils/calculation_layer.py
| def clear_memory(self):
""" released unused memory in current memory pool. """
self.mempool_used.clear()
self.mempool.free_all_blocks()
self.pinned_mempool.free_all_blocks()
|
dot
dot(A, B, gpu_out: bool = True, sync: bool = True)
dot matrix A and matrix B
Parameters:
-
A(np.array<np.complex>)
–
-
B(np.array<np.complex>)
–
-
gpu_out(bool)
–
return result from GPU into CPU
Returns:
Source code in QuICT/ops/utils/calculation_layer.py
| def dot(self, A, B, gpu_out: bool = True, sync: bool = True):
""" dot matrix A and matrix B
Args:
A(np.array<np.complex>): the matrix A
B(np.array<np.complex>): the matrix B
gpu_out(bool): return result from GPU into CPU
Returns:
np.array<np.complex>: A * B
"""
gpu_A = self._var_normalized(A)
gpu_B = self._var_normalized(B)
result = GPUCalculator.dot(gpu_A, gpu_B, gpu_out, sync)
return self._result_normalized(result, gpu_out)
|
dtoh
mv target from GPU device into host.
Source code in QuICT/ops/utils/calculation_layer.py
| def dtoh(self, target):
""" mv target from GPU device into host. """
if type(target) is cp.ndarray:
return target.get()
if type(target) is weakref.ref:
return target().get()
raise ("The given value not in GPU.")
|
htod
mv target from host into GPU device.
Source code in QuICT/ops/utils/calculation_layer.py
| def htod(self, target):
""" mv target from host into GPU device. """
if type(target) is not cp.ndarray:
cp_t = cp.array(target)
weak_r = weakref.ref(cp_t)
self.mempool_used.append(cp_t)
return weak_r
raise ("The given value has been added in the GPU.")
|
tensor
tensor(A, B, gpu_out: bool = True, sync: bool = True)
tensor A and B
Parameters:
-
A(np.array<np.complex>)
–
-
B(np.array<np.complex>)
–
-
gpu_out(bool)
–
return result from GPU into CPU
Returns:
-
–
np.array: the tensor result A ⊗ B
Source code in QuICT/ops/utils/calculation_layer.py
| def tensor(self, A, B, gpu_out: bool = True, sync: bool = True):
""" tensor A and B
Args:
A(np.array<np.complex>): the matrix A
B(np.array<np.complex>): the matrix B
gpu_out(bool): return result from GPU into CPU
Returns:
np.array<np.complex>: the tensor result A ⊗ B
"""
gpu_A = self._var_normalized(A)
gpu_B = self._var_normalized(B)
result = GPUCalculator.tensor(gpu_A, gpu_B, gpu_out, sync)
return self._result_normalized(result, gpu_out)
|