MCPcopy Create free account
hub / github.com/QuEST-Kit/QuEST / assertMatrixFitsInGpuMem

Function assertMatrixFitsInGpuMem

quest/src/core/validation.cpp:1946–2000  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1944}
1945
1946void assertMatrixFitsInGpuMem(int numQubits, bool isDense, int isDistrib, int isGpu, int numEnvNodes, const char* caller) {
1947
1948 // 'isDistrib' can be 0 (user-disabled, or matrix is a local type), 1 (user-forced)
1949 // or modeflag::USE_AUTO=-1 (automatic; the type can be distributed but the user has
1950 // not forced it). Currently, only distributed diagonal matrices are supported, so
1951 // isDistrib must be specifically 0 for dense matrices.
1952 if (isDense && isDistrib != 0)
1953 error_validationEncounteredUnsupportedDistributedDenseMatrix();
1954
1955 // 'isGpu' can be 0 (user-disabled, or matrix is a local type), 1 (user-forced), or
1956 // modeflag::USE_AUTO=-1 (automatic; the type can be GPU-accel but the user has not forced it).
1957 // Whenever GPU isn't forced, we do not need to check there's sufficient GPU memory, because
1958 // if there's insufficient, the auto-deployer will never choose it. So proceed only if GPU is forced.
1959 if (isGpu != 1)
1960 return;
1961
1962 // we consult the current available local GPU memory (being more strict than is possible for RAM)
1963 size_t localCurrGpuMem = gpu_getCurrentAvailableMemoryInBytes();
1964
1965 // check whether matrix (considering if distributed) fits between node memory(s).
1966 // note this sets numMatrNodes=1 only when distribution is impossible/switched-off,
1967 // but not when it would later be automatically disabled. That's fine; the auto-deployer
1968 // will never disable distribution if the local GPU can't store the entire matrix, so we
1969 // don't need to validate the auto-deployed-to-non-distributed scenario. We only need to
1970 // ensure that auto-deploying-to-distribution is permitted by memory capacity. Note too
1971 // that the distinction between (env.isDistributed) and (env.numNodes>1) is unimportant
1972 // for matrix structs because they never store communication buffers.
1973 int numMatrNodes = (isDistrib == 0)? 1 : numEnvNodes;
1974 bool matrFitsInMem = mem_canMatrixFitInMemory(numQubits, isDense, numMatrNodes, localCurrGpuMem);
1975
1976 // specialise error message to whether matrix is distributed and dense or diag
1977 string msg = (isDense)?
1978 report::NEW_LOCAL_COMP_MATR_CANNOT_FIT_INTO_GPU_MEM :
1979 ((numMatrNodes == 1)?
1980 report::NEW_LOCAL_DIAG_MATR_CANNOT_FIT_INTO_GPU_MEM :
1981 report::NEW_DISTRIB_DIAG_MATR_CANNOT_FIT_INTO_GPU_MEM );
1982
1983 tokenSubs vars = {
1984 {"${NUM_QUBITS}", numQubits},
1985 {"${QCOMP_BYTES}", sizeof(qcomp)},
1986 {"${VRAM_SIZE}", localCurrGpuMem}};
1987
1988 if (numMatrNodes > 1) {
1989 vars["${NUM_NODES}"] = numMatrNodes;
1990 vars["${NUM_QB_MINUS_LOG_NODES}"] = numQubits - logBase2(numMatrNodes);
1991 }
1992
1993 /// @todo
1994 /// seek expensive node consensus in case of heterogeneous GPU hardware - alas this may
1995 /// induce unnecessary slowdown (due to sync and broadcast) in applications allocating many
1996 /// small matrices in the GPU. If this turns out to be the case, we could opt to
1997 /// enforce consensus only when the needed memory is large (e.g. >1GB) and ergo the
1998 /// chance of it fitting into some GPU's memory but not others isn't negligible.
1999 assertAllNodesAgreeThat(matrFitsInMem, msg, vars, caller);
2000}
2001
2002void assertNewMatrixParamsAreValid(int numQubits, int useDistrib, int useGpu, int useMultithread, bool isDenseType, const char* caller) {
2003

Callers 1

Tested by

no test coverage detected