From 6d3588d189a831f04d3add7aedc754e074c3f983 Mon Sep 17 00:00:00 2001 From: Jacob Merson Date: Mon, 18 Feb 2019 12:18:46 -0500 Subject: [PATCH 1/3] Updated features from fasttmp failure --- src/las.h | 24 +++++++++++ src/lasSparse.cc | 106 ++++++++++++++++++++++++++++++++++++----------- src/lasSparse.h | 6 +++ 3 files changed, 112 insertions(+), 24 deletions(-) diff --git a/src/las.h b/src/las.h index 16d1265..bdb8a9f 100644 --- a/src/las.h +++ b/src/las.h @@ -280,6 +280,30 @@ namespace las }; template ScalarVecMult * getScalarVecMult(); + class MatDiagonal + { + public: + virtual void exec(scalar s, Mat * m, Vec *& v) = 0; + virtual ~MatDiagonal() {} + }; + template + MatDiagonal * getMatDiagonal(); + class MatDiagonalInverse + { + public: + virtual void exec(scalar s, Mat * m, Vec *& v) = 0; + virtual ~MatDiagonalInverse() {} + }; + template + MatDiagonalInverse * getMatDiagonalInverse(); + class HadamardProduct + { + public: + virtual void exec(Vec * v1, Vec * v2, Vec * v3) = 0; + virtual ~HadamardProduct() {} + }; + template + HadamardProduct * getHadamardProduct(); /* * Finalize routines which must be called on a matrix when switching from * add mode to set mode diff --git a/src/lasSparse.cc b/src/lasSparse.cc index 61f7e74..1db8f3a 100644 --- a/src/lasSparse.cc +++ b/src/lasSparse.cc @@ -5,30 +5,6 @@ namespace las class sparseMatVec : public MatVecMult { public: - /* - void exec(Mat * x, Vec * a, Vec * b) - { - csrMat * cm = getCSRMat(x); - CSR * csr = cm->getCSR(); - lasVec * sa = getLASVec(a); - lasVec * sb = getLASVec(b); - int nr = csr->getNumRows(); - int nc = csr->getNumCols(); - int la = sa->size(); - int lb = sb->size(); - assert(nc == la && "Matrix columns and lhs vector length must match"); - assert(nr == lb && "Matrix rows and rhs vector length must match"); - for (int rw = 0; rw < nr; ++rw) - { - double val = 0; - for (int cl = 0; cl < nc; ++cl) - { - val += (*cm)(rw, cl) * (*sa)[cl]; - } - (*sb)[rw] = val; - } - } - */ void exec(Mat * x, Vec * a, Vec * b) { csrMat * cm = getCSRMat(x); @@ -247,6 +223,67 @@ namespace las v3 = reinterpret_cast(sv3); } }; + class sparseMatDiagonal : public MatDiagonal + { + void exec(scalar s, Mat * m, Vec *& v) + { + csrMat * cm = getCSRMat(m); + CSR * csr = cm->getCSR(); + lasVec * sv; + assert(csr->getNumCols() == csr->getNumRows()); + if (v) + { + destroyVector(v); + sv = reinterpret_cast(createVector(csr->getNumRows())); + } + else + { + sv = reinterpret_cast(createVector(csr->getNumRows())); + } + for(int i=0; igetNumRows(); ++i) { + (*sv)[i] = s*(*cm)(i,i); + } + v = reinterpret_cast(sv); + } + }; + class sparseMatDiagonalInverse : public MatDiagonalInverse + { + void exec(scalar s, Mat * m, Vec *& v) + { + csrMat * cm = getCSRMat(m); + CSR * csr = cm->getCSR(); + lasVec * sv; + assert(csr->getNumCols() == csr->getNumRows()); + if (v) + { + destroyVector(v); + sv = reinterpret_cast(createVector(csr->getNumRows())); + } + else + { + sv = reinterpret_cast(createVector(csr->getNumRows())); + } + for(int i=0; igetNumRows(); ++i) { + (*sv)[i] = s/(*cm)(i,i); + } + v = reinterpret_cast(sv); + } + }; + class sparseHadamardProduct : public HadamardProduct + { + void exec(Vec * v1, Vec * v2, Vec * v3) + { + lasVec * sv1 = getLASVec(v1); + lasVec * sv2 = getLASVec(v2); + lasVec * sv3 = getLASVec(v3); + assert(sv1->size() == sv2->size()); + assert(sv1->size() == sv3->size()); + for(int i=0; isize(); ++i) + { + (*sv3)[i] = (*sv1)[i]*(*sv2)[i]; + } + }; + }; template <> MatVecMult * getMatVecMult() { @@ -282,4 +319,25 @@ namespace las if (vva == nullptr) vva = new sparseVecVecAdd; return vva; } + template <> + MatDiagonal * getMatDiagonal() + { + static sparseMatDiagonal * dia = nullptr; + if (dia == nullptr) dia = new sparseMatDiagonal; + return dia; + } + template <> + MatDiagonalInverse * getMatDiagonalInverse() + { + static sparseMatDiagonalInverse * dia = nullptr; + if (dia == nullptr) dia = new sparseMatDiagonalInverse; + return dia; + } + template <> + HadamardProduct * getHadamardProduct() + { + static sparseHadamardProduct * hp = nullptr; + if (hp == nullptr) hp = new sparseHadamardProduct; + return hp; + } } // namespace las diff --git a/src/lasSparse.h b/src/lasSparse.h index cc8291e..f7427cd 100644 --- a/src/lasSparse.h +++ b/src/lasSparse.h @@ -21,6 +21,12 @@ namespace las template <> VecVecAdd * getVecVecAdd(); template <> + MatDiagonal * getMatDiagonal(); + template <> + MatDiagonalInverse * getMatDiagonalInverse(); + template <> + HadamardProduct * getHadamardProduct(); + template <> void finalizeMatrix(Mat * mat); template <> void finalizeVector(Vec * vec); From b019a77d3786bdecff67c0454bb708bd1a4bd209 Mon Sep 17 00:00:00 2001 From: Jacob Merson Date: Mon, 29 Jul 2019 15:33:21 -0400 Subject: [PATCH 2/3] compile on dcs --- CMakeLists.txt | 5 ++--- core/CMakeLists.txt | 2 +- scripts/config_dcs.sh | 25 +++++++++++++++++++++++++ scripts/config_erp.sh | 16 ++++++++++++++++ src/CMakeLists.txt | 6 +++--- src/lasInline.h | 4 ++-- src/lasSparse.cc | 32 ++++++++++++++++++++++++++++++++ src/lasSparse_impl.h | 32 -------------------------------- src/lasSparskitExterns.cc | 2 +- src/lasSparskitExterns.h | 2 +- test/CMakeLists.txt | 4 ++-- 11 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 scripts/config_dcs.sh create mode 100644 scripts/config_erp.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 64192af..54f2a95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,9 +39,8 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Cray") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") # todo : check for regular xl vs bg/q xl compiler # currently assuming bg/q - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -qlanglvl=extended0x -O5 -qhot=level=0 -qsimd=auto -qmaxmem=-1 -qstrict -qstrict_induction -qreport") - # these definitions are BGQ specific, but for now the only place we use XL compiler is on BGQ - #add_definitions(-DBGQ) + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -qlanglvl=extended0x") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -qlanglvl=extended0x -O5 -qhot=level=0 -qsimd=auto -qmaxmem=-1 -qstrict -qstrict_induction -qreport -Wall") elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") # todo : set intel-specific cxx flags set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 098523d..e6c46a5 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -26,7 +26,7 @@ endif() add_library(las_core STATIC ${las_core_sources}) if(${CMAKE_VERSION} VERSION_GREATER "3.8.2") - target_compile_features(las_core PUBLIC cxx_std_11) + #target_compile_features(las_core PUBLIC cxx_std_11) endif() if(MPI_COMPILE_FLAGS) set_target_properties(las_core PROPERTIES COMPILE_FLAGS ${MPI_CXX_COMPILE_DEFINITIONS}) diff --git a/scripts/config_dcs.sh b/scripts/config_dcs.sh new file mode 100644 index 0000000..3ba5f17 --- /dev/null +++ b/scripts/config_dcs.sh @@ -0,0 +1,25 @@ +#!/bin/bash +#mpicc=/gpfs/u/home/PASC/PASCmrsn/scratch/test_compile/mpicc +#mpicxx=/gpfs/u/home/PASC/PASCmrsn/scratch/test_compile/mpicxx +#mpif77=/gpfs/u/home/PASC/PASCmrsn/scratch/test_compile/mpif77 +export OMPI_CXX=xlc++_r + + cmake /gpfs/u/home/PASC/PASCmrsn/barn/las/ \ + -DCMAKE_C_COMPILER=`which mpicc` \ + -DCMAKE_CXX_COMPILER=`which mpicxx` \ + -DCMAKE_Fortran_COMPILER=`which mpif77` \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=0 \ + -DSCOREC_DIR=/gpfs/u/home/PASC/PASCmrsn/scratch/dcs/install/core/lib/cmake/SCOREC/ \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/gpfs/u/home/PASC/PASCmrsn/scratch/dcs/install/las \ + -DPETSC_DIR="$PETSC_DIR" \ + -DPETSC_ARCH="$PETSC_ARCH" \ + -DBUILD_SPARSKIT=ON \ + -DWITH_KOKKOS=FALSE \ + -DBUILD_TESTS=FALSE \ + -DCMAKE_CXX_FLAGS="-Ofast -std=c++11 -Wall" \ + -DCMAKE_C_FLAGS="-Ofast -Wall" \ + -DCMAKE_Fortran_FLAGS="-Ofast -Wall" + #-DCMAKE_C_FLAGS="-O5" \ + #-DCMAKE_CXX_FLAGS="-O5 -sdt=c++11" \ + #-DCMAKE_Fortran_FLAGS="-O5" \ diff --git a/scripts/config_erp.sh b/scripts/config_erp.sh new file mode 100644 index 0000000..3376244 --- /dev/null +++ b/scripts/config_erp.sh @@ -0,0 +1,16 @@ +#!/bin/bash +PREFIX=/gpfs/u/home/PASC/PASCmrsn/scratch/install-erp/las + + cmake /gpfs/u/home/PASC/PASCmrsn/barn/las/ \ + -DCMAKE_C_COMPILER=`which mpicc` \ + -DCMAKE_CXX_COMPILER=`which mpicxx` \ + -DCMAKE_Fortran_COMPILER=`which mpif77` \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=0 \ + -DSCOREC_DIR=/gpfs/u/home/PASC/PASCmrsn/scratch/install-erp/core/lib/cmake/SCOREC/ \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DPETSC_DIR="$PETSC_DIR" \ + -DPETSC_ARCH="$PETSC_ARCH" \ + -DBUILD_SPARSKIT=ON \ + -DWITH_KOKKOS=FALSE \ + -DBUILD_TESTS=FALSE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc3a084..613e2a0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -89,11 +89,11 @@ configure_file(lasConfig.h.in "${CMAKE_CURRENT_SOURCE_DIR}/lasConfig.h" @ONLY) set(las_headers ${las_headers} ${las_install} lasConfig.h) add_library(las STATIC ${las_sources}) -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "XL") +if("${HOST}" STREQUAL "q.ccni.rpi.edu") target_compile_definitions(las PUBLIC "-DBGQ") endif() if(${CMAKE_VERSION} VERSION_GREATER "3.8.2") - target_compile_features(las PUBLIC cxx_std_11) + #target_compile_features(las PUBLIC cxx_std_11) endif() if(CUDA_FOUND) set_target_properties(las PROPERTIES CUDA_SEPARABLE_COMPILATION ON) @@ -131,7 +131,7 @@ function(add_backend backend headers libraries) ${CMAKE_CURRENT_BINARY_DIR}/capi/las_capi_${backend}.cc ${headers}) if(${CMAKE_VERSION} VERSION_GREATER "3.8.2") - target_compile_features(${capi_lib} PUBLIC cxx_std_11) + #target_compile_features(${capi_lib} PUBLIC cxx_std_11) endif() target_include_directories(${capi_lib} PUBLIC $ diff --git a/src/lasInline.h b/src/lasInline.h index d28c8de..4f56c53 100644 --- a/src/lasInline.h +++ b/src/lasInline.h @@ -5,8 +5,8 @@ #define LAS_INLINE inline #elif defined(__INTEL_COMPILER) #define LAS_INLINE __forceinline -#elif defined(__xlc__) -#define LAS_INLINE __attribute__((always_inline)) +#elif defined(__xlc__) || defined(__ibmxl__) +#define LAS_INLINE inline __attribute__((always_inline)) #elif defined(__GNUC__) || defined(__GNUG__) #define LAS_INLINE inline //__attribute__((always_inline)) diff --git a/src/lasSparse.cc b/src/lasSparse.cc index 61f7e74..f93515c 100644 --- a/src/lasSparse.cc +++ b/src/lasSparse.cc @@ -282,4 +282,36 @@ namespace las if (vva == nullptr) vva = new sparseVecVecAdd; return vva; } + template <> + LasCreateMat * getMatBuilder(int) + { + static csrMatBuilder * mb = nullptr; + if(mb == nullptr) + mb = new csrMatBuilder; + return mb; + } + template <> + LasCreateVec * getVecBuilder(int) + { + static csrVecBuilder * vb = nullptr; + if(vb == nullptr) + vb = new csrVecBuilder; + return vb; + } + template <> + LasOps * getLASOps() + { + static sparse * ops = nullptr; + if(ops == nullptr) + ops = new sparse; + return ops; + } + template <> + void finalizeMatrix(Mat * mat){}; + template <> + void finalizeVector(Vec * vec){}; + template <> + void destroySparsity(Sparsity * sprs) { + delete reinterpret_cast(sprs); + } } // namespace las diff --git a/src/lasSparse_impl.h b/src/lasSparse_impl.h index ca46dfa..32931e6 100644 --- a/src/lasSparse_impl.h +++ b/src/lasSparse_impl.h @@ -95,14 +95,6 @@ namespace las destroyCSRMatrix(m); } }; - template <> - LAS_INLINE LasCreateMat * getMatBuilder(int) - { - static csrMatBuilder * mb = nullptr; - if(mb == nullptr) - mb = new csrMatBuilder; - return mb; - } class csrVecBuilder : public LasCreateVec { public: @@ -130,14 +122,6 @@ namespace las return createVector(rows); } }; - template <> - LAS_INLINE LasCreateVec * getVecBuilder(int) - { - static csrVecBuilder * vb = nullptr; - if(vb == nullptr) - vb = new csrVecBuilder; - return vb; - } class sparse : public LasOps { public: @@ -245,21 +229,5 @@ namespace las void _restore(Vec*, scalar *&) { } }; - template <> - LAS_INLINE LasOps * getLASOps() - { - static sparse * ops = nullptr; - if(ops == nullptr) - ops = new sparse; - return ops; - } - template <> - LAS_INLINE void finalizeMatrix(Mat * mat){}; - template <> - LAS_INLINE void finalizeVector(Vec * vec){}; - template <> - LAS_INLINE void destroySparsity(Sparsity * sprs) { - delete reinterpret_cast(sprs); - } } #endif diff --git a/src/lasSparskitExterns.cc b/src/lasSparskitExterns.cc index 43d4d64..b1410cb 100644 --- a/src/lasSparskitExterns.cc +++ b/src/lasSparskitExterns.cc @@ -1,6 +1,6 @@ #include "lasSparskitExterns.h" #include -#ifdef BGQ +#if defined(BGQ) || defined(__ibmxl__) void ilut_(int *n,double a[],int ja[],int ia[],int *lfil,double *droptol,double *alu,int *jlu,int *ju,int *iwk,double *w,int *jw,int *ierr) { ilut(n,a,ja,ia,lfil,droptol,alu,jlu,ju,iwk,w,jw,ierr); diff --git a/src/lasSparskitExterns.h b/src/lasSparskitExterns.h index c76dd02..b1a6b9f 100644 --- a/src/lasSparskitExterns.h +++ b/src/lasSparskitExterns.h @@ -2,7 +2,7 @@ #define LAS_SPARSKIT_EXTERNS_H_ #include #include -#ifdef BGQ +#if defined(BGQ) || defined(__ibmxl__) extern "C" { void ilut(int *,double a[],int ja[],int ia[],int *,double *,double *,int *,int *,int *,double *,int *,int *); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 813f018..ad57c3a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,7 +2,7 @@ function(add_mpi_test name file no_mpi_proc) message(STATUS "Adding mpi test " ${name}) add_executable(${name} ${file}) if(${CMAKE_VERSION} VERSION_GREATER "3.8.2") - target_compile_features(${name} PUBLIC cxx_std_11) + #target_compile_features(${name} PUBLIC cxx_std_11) endif() target_include_directories(${name} PUBLIC ${test_header_dir}) if("${HOST}" STREQUAL "q.ccni.rpi.edu") @@ -25,7 +25,7 @@ function(simple_test name file) message(STATUS "Adding test " ${name}) add_executable(${name} ${file}) if(${CMAKE_VERSION} VERSION_GREATER "3.8.2") - target_compile_features(${name} PUBLIC cxx_std_11) + #target_compile_features(${name} PUBLIC cxx_std_11) endif() if("${HOST}" STREQUAL "q.ccni.rpi.edu") set_target_properties(${name} PROPERTIES LINK_SEARCH_START_STATIC 1) From a9fe4c2031560f46ce687a65fc8498c1cc8104c8 Mon Sep 17 00:00:00 2001 From: Jacob Merson Date: Mon, 13 Jan 2020 16:05:12 -0500 Subject: [PATCH 3/3] updates to support memory leak reductions in biotissue --- src/las.h | 8 ++++++++ src/lasDense_impl.h | 4 ++++ src/lasPETSc_impl.h | 13 +++++++++++++ src/lasSparse_impl.h | 4 ++++ src/lasSparskitExterns.cc | 15 +++++++++------ src/lasVec_impl.h | 22 +++++++++++++++++++--- 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/las.h b/src/las.h index bdb8a9f..e746a39 100644 --- a/src/las.h +++ b/src/las.h @@ -156,6 +156,14 @@ namespace las * @param cm The comm over which the vector is collective. */ virtual Vec * create(unsigned lcl, unsigned bs, MPI_Comm cm) = 0; + /** + * Create a vector from an existing array + * @param data The array which the vector will use as data storage + * @param lcl The local number of rows (per-process in cm) + * @param bs The block size (should be the same over cm) + * @param cm The comm over which the vector is collective. + */ + virtual Vec * create(scalar * data, unsigned lcl, unsigned bs, MPI_Comm cm)=0; virtual void destroy(Vec * v) = 0; /** * Create a vector suitable to act as the RHS vector to a diff --git a/src/lasDense_impl.h b/src/lasDense_impl.h index 1798dd3..b3c947e 100644 --- a/src/lasDense_impl.h +++ b/src/lasDense_impl.h @@ -99,6 +99,10 @@ namespace las { return createVector(lcl); } + virtual Vec * create(scalar * data, unsigned lcl, unsigned, MPI_Comm) + { + return createVector(data, lcl); + } virtual void destroy(Vec * v) { destroyVector(v); diff --git a/src/lasPETSc_impl.h b/src/lasPETSc_impl.h index d085389..6f54f2d 100644 --- a/src/lasPETSc_impl.h +++ b/src/lasPETSc_impl.h @@ -230,6 +230,15 @@ namespace las CHKERRABORT(LAS_COMM_WORLD, ierr); return reinterpret_cast(v); } + LAS_INLINE las::Vec * createPetscVector(scalar * data, unsigned l, unsigned bs, MPI_Comm cm = LAS_COMM_WORLD) + { + ::Vec * v = new ::Vec; + PetscErrorCode ierr = VecCreateMPIWithArray(cm, bs, l,PETSC_DECIDE,data, v); + CHKERRABORT(LAS_COMM_WORLD, ierr); + ierr = VecSetOption(*v,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE); + CHKERRABORT(LAS_COMM_WORLD, ierr); + return reinterpret_cast(v); + } LAS_INLINE void destroyPetscVec(las::Vec * v) { PetscErrorCode ierr = VecDestroy(getPetscVec(v)); @@ -255,6 +264,10 @@ namespace las { return createPetscVector(lcl,bs,cm); } + virtual Vec * create(scalar * data, unsigned lcl, unsigned bs, MPI_Comm cm) + { + return createPetscVector(data, lcl,bs,cm); + } virtual Vec * createRHS(Mat * m) { return createRHSVec(m); diff --git a/src/lasSparse_impl.h b/src/lasSparse_impl.h index 32931e6..1531ae5 100644 --- a/src/lasSparse_impl.h +++ b/src/lasSparse_impl.h @@ -103,6 +103,10 @@ namespace las { return createVector(lcl); } + virtual Vec * create(scalar * data, unsigned lcl, unsigned, MPI_Comm) + { + return createVector(data, lcl); + } virtual void destroy(Vec * v) { destroyVector(v); diff --git a/src/lasSparskitExterns.cc b/src/lasSparskitExterns.cc index b1410cb..9b9176c 100644 --- a/src/lasSparskitExterns.cc +++ b/src/lasSparskitExterns.cc @@ -59,11 +59,14 @@ namespace las matrix.assign(matrix.size(),0.0); } void SparskitBuffers::resizeMatrixBuffer(int newSize) { - assert((newSize-matrixLength()) > 0); - heuristic_length = newSize; - matrix.resize(heuristic_length); - cols.resize(heuristic_length); - assert(cols.size() == heuristic_length); - assert(matrix.size() == heuristic_length); + // only support increasing the buffer size + if(newSize > matrixLength()) + { + heuristic_length = newSize; + matrix.resize(heuristic_length); + cols.resize(heuristic_length); + assert(cols.size() == heuristic_length); + assert(matrix.size() == heuristic_length); + } } }; diff --git a/src/lasVec_impl.h b/src/lasVec_impl.h index 6b85b2f..0122bb1 100644 --- a/src/lasVec_impl.h +++ b/src/lasVec_impl.h @@ -5,6 +5,7 @@ #include #include #include // memset +#include namespace las { class lasVec @@ -12,12 +13,22 @@ namespace las private: scalar * vls; int cnt; + // this is a data location that any negative indices will + // sum into + scalar dummy_data; public: lasVec(int n) : vls(nullptr) , cnt(n) + , dummy_data(0) + { + alloc((void**)&vls,sizeof(scalar)*n); + } + lasVec(scalar * data, int n) + : vls(data) + , cnt(n) + , dummy_data(0) { - alloc((void**)&vls,sizeof(scalar)*(n+1)); } ~lasVec() { @@ -27,7 +38,7 @@ namespace las { assert(idx < cnt); if(idx < 0) - idx = cnt; + return dummy_data; return vls[idx]; } void setVls(scalar * values) { @@ -41,7 +52,8 @@ namespace las // too coupled to the implementation to leave external void zero() { - memset(&vls[0],0,sizeof(scalar)*(cnt+1)); + memset(&vls[0],0,sizeof(scalar)*cnt); + dummy_data = 0; } }; LAS_INLINE lasVec * getLASVec(Vec * v) @@ -52,6 +64,10 @@ namespace las { return reinterpret_cast(new lasVec(n)); } + LAS_INLINE Vec * createVector(scalar * data, unsigned n) + { + return reinterpret_cast(new lasVec(data,n)); + } LAS_INLINE void destroyVector(Vec * v) { delete getLASVec(v);