From 3bf263c4f34621294ebd97c7d8aaedd156fe4d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Wed, 8 Jan 2020 15:18:25 +0200 Subject: [PATCH] Copying of T-matrix operations Former-commit-id: dea91f97e5e72146039868ab5f0c8ac5e7ea7a57 --- qpms/qpms_error.h | 9 ++++++++ qpms/tmatrices.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ qpms/tmatrices.h | 7 +++++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/qpms/qpms_error.h b/qpms/qpms_error.h index 10fb7b8..393157c 100644 --- a/qpms/qpms_error.h +++ b/qpms/qpms_error.h @@ -56,6 +56,15 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types); (size_t) (size));\ } +#define QPMS_CRASHING_MALLOCPY(dest, src, size) {\ + (dest) = malloc(size);\ + if(QPMS_UNLIKELY(!(dest) && (size)))\ + qpms_pr_debug_at_flf(__FILE__,__LINE__,__func__,\ + "Allocation of %zd bytes for " #dest " failed.",\ + (size_t) (size));\ + memcpy((dest), (src), (size));\ +} + #define QPMS_CRASHING_CALLOC(pointer, nmemb, size) {\ (pointer) = calloc((nmemb), (size));\ if(QPMS_UNLIKELY(!(pointer) && (nmemb) && (size)))\ diff --git a/qpms/tmatrices.c b/qpms/tmatrices.c index e13ec1c..8304d06 100644 --- a/qpms/tmatrices.c +++ b/qpms/tmatrices.c @@ -1040,6 +1040,60 @@ void qpms_tmatrix_operation_clear(qpms_tmatrix_operation_t *f) { } } +void qpms_tmatrix_operation_copy(qpms_tmatrix_operation_t *dest, const qpms_tmatrix_operation_t *src) { + memcpy(dest, src, sizeof(qpms_tmatrix_operation_t)); + switch(dest->typ) { + case QPMS_TMATRIX_OPERATION_NOOP: + break; + case QPMS_TMATRIX_OPERATION_LRMATRIX: + QPMS_CRASHING_MALLOCPY(dest->op.lrmatrix.m, src->op.lrmatrix.m, + sizeof(complex double) * src->op.lrmatrix.m_size); + dest->op.lrmatrix.owns_m = true; + break; + case QPMS_TMATRIX_OPERATION_SCMULZ: + QPMS_CRASHING_MALLOCPY(dest->op.scmulz.m, src->op.scmulz.m, + sizeof(complex double) * src->op.scmulz.m_size); + dest->op.scmulz.owns_m = true; + break; + case QPMS_TMATRIX_OPERATION_IROT3: + break; + case QPMS_TMATRIX_OPERATION_IROT3ARR: + QPMS_CRASHING_MALLOCPY(dest->op.irot3arr.ops, src->op.irot3arr.ops, + src->op.irot3arr.n * sizeof(qpms_irot3_t)); + dest->op.irot3arr.owns_ops = true; + break; + case QPMS_TMATRIX_OPERATION_FINITE_GROUP_SYMMETRISE: // Group never owned + break; + case QPMS_TMATRIX_OPERATION_COMPOSE_SUM: + { + struct qpms_tmatrix_operation_compose_sum * const o = + &(dest->op.compose_sum); + QPMS_CRASHING_MALLOC(o->ops, o->n * sizeof(*(o->ops))); + QPMS_CRASHING_MALLOC(o->opmem, o->n * sizeof(*(o->opmem))); + for(size_t i = 0; i < o->n; ++i) { + qpms_tmatrix_operation_copy(o->opmem + i, src->op.compose_sum.ops[i]); + o->ops[i] = o->opmem + i; + } + } + break; + case QPMS_TMATRIX_OPERATION_COMPOSE_CHAIN: + { + struct qpms_tmatrix_operation_compose_chain * const o = + &(dest->op.compose_chain); + QPMS_CRASHING_MALLOC(o->ops, o->n * sizeof(*(o->ops))); + QPMS_CRASHING_MALLOC(o->opmem, o->n * sizeof(*(o->opmem))); + for(size_t i = 0; i < o->n; ++i) { + qpms_tmatrix_operation_copy(o->opmem + i, src->op.compose_chain.ops[i]); + o->ops[i] = o->opmem + i; + } + } + break; + default: + QPMS_WTF; + } +} + + qpms_tmatrix_t *qpms_tmatrix_apply_operation( const qpms_tmatrix_operation_t *f, const qpms_tmatrix_t *orig) { // Certain operations could be optimized, but the effect would be marginal. diff --git a/qpms/tmatrices.h b/qpms/tmatrices.h index c9f819f..fc54edd 100644 --- a/qpms/tmatrices.h +++ b/qpms/tmatrices.h @@ -555,6 +555,7 @@ struct qpms_tmatrix_operation_lrmatrix { /// Raw matrix data of \a M in row-major order. /** The matrix must be taylored for the given bspec! */ complex double *m; + size_t m_size; ///< Total size of \a m matrix in terms of sizeof(complex double). bool owns_m; ///< Whether \a m is owned by this; }; @@ -584,7 +585,8 @@ struct qpms_tmatrix_operation_compose_chain { struct qpms_tmatrix_operation_scmulz { /// Raw matrix data of \a M in row-major order. /** The matrix must be taylored for the given bspec! */ - complex double *m; + complex double *m; + size_t m_size; ///< Total size of \a m matrix in terms of sizeof(complex double). bool owns_m; ///< Whether \a m is owned by this. }; @@ -628,6 +630,9 @@ qpms_tmatrix_t *qpms_tmatrix_apply_operation_inplace(const qpms_tmatrix_operatio */ void qpms_tmatrix_operation_clear(qpms_tmatrix_operation_t *f); +/// (Recursively) copies an qpms_tmatrix_operation_t. +/** Makes copies of all the internal data and takes ownership over them if needed */ +void qpms_tmatrix_operation_copy(qpms_tmatrix_operation_t *target, const qpms_tmatrix_operation_t *src); #if 0 // Abstract types that describe T-matrix/particle/scatsystem symmetries