diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..5a506baa8863598154fb8ee5c75a43c72430a8c6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,76 @@ +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: true +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: false +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: false +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 0 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 0 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +PenaltyBreakBeforeFirstCallParameter: 1400 +PenaltyBreakComment: 1400 +PenaltyBreakFirstLessLess: 140000 +PenaltyBreakString: 1400 +PenaltyExcessCharacter: 1 +PointerAlignment: Left +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: Never +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: true +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +DisableFormat: false diff --git a/Addons/CKernelApi/CMakeLists.txt b/Addons/CKernelApi/CMakeLists.txt index 9cbc5a189271ebbfdf33b35dcced90828235fd8f..9bd5b14db9a16028b54b6798c28720eae369cef0 100644 --- a/Addons/CKernelApi/CMakeLists.txt +++ b/Addons/CKernelApi/CMakeLists.txt @@ -22,7 +22,7 @@ if(SCALFMM_ADDON_CKERNELAPI) file( GLOB_RECURSE source_lib_files Src/*.cpp ) # Adding cpp files to project - add_library( scalfmmckernelapi STATIC ${source_lib_files} ) + add_library( scalfmmckernelapi ${source_lib_files} ) # Add blas library (even if it is set to off) target_link_libraries( scalfmmckernelapi scalfmm) @@ -35,7 +35,7 @@ if(SCALFMM_ADDON_CKERNELAPI) ) # Install lib - install( TARGETS scalfmmckernelapi ARCHIVE DESTINATION lib ) + install( TARGETS scalfmmckernelapi ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) # Install header SET(my_include_dirs "Src") diff --git a/Addons/CKernelApi/Src/CScalfmmApi.h b/Addons/CKernelApi/Src/CScalfmmApi.h index 3eac6ca2dc3401caf41a188f8df13f308a109f75..d9809af0f0edd81ab2184cf40423537984d1ed89 100644 --- a/Addons/CKernelApi/Src/CScalfmmApi.h +++ b/Addons/CKernelApi/Src/CScalfmmApi.h @@ -145,10 +145,10 @@ typedef void (*Callback_free_cell)(void*); /** * @brief Callback used to know the size of userData. * @param level current level of current cell - * @param userData Datas that will be serialize * @param morton_index of the current cell + * @param userData : ptr to user's kernel */ -typedef FSize (*Callback_get_cell_size)(int level, void * userDatas, long long morton_index); +typedef FSize (*Callback_get_cell_size)(int level, long long morton_index, void * userData); /** * @brief Callback used to serialize userdata inside an array of size @@ -159,6 +159,39 @@ typedef FSize (*Callback_get_cell_size)(int level, void * userDatas, long long m */ typedef void (*Callback_copy_cell)(void * userDatas, FSize size, void * memoryAllocated); +/** + * @brief Callback used by scalfmm to know the size needed by the user + * to store its local datas linked to a leaf. + * + * @param nbParts : number of point inside current Leaf + * @return Size (in bytes) needed to serialize the user datas + */ +typedef FSize (*Callback_get_leaf_size)(FSize nbParts); + +/** + * @brief Callback used by scalfmm to serialize the leaf user data. + * + * @param Morton MortonIndex of current Leaf + * @param nbParts : number of point inside current Leaf + * @param userdata : leaf User data + * @param memAllocated : Ptr to an array of size = + * Callback_get_leaf_size(...), to be filled by the user. + */ +typedef void (*Callback_copy_leaf)(FSize nbParts, void * userDatas, void * memAllocated); + + +/** + * @brief Callback used by scalfmm to retreive leaf data from an array + * (previously filled by the user through Callback_copy_leaf) + * + * @param Morton MortonIndex of current Leaf + * @param nbParts : number of point inside current Leaf + * @param memAllocated : Ptr to an array of size = + * Callback_get_leaf_size(...), to be read by the user in order to + * re-build its leaf. + * @return new userdata local to the leaf + */ +typedef void * (*Callback_restore_leaf)(FSize nbParts, void * memAllocated); /** * @brief Callback called if scalfmm_finalize_cell is called. @@ -214,10 +247,18 @@ typedef struct User_Scalfmm_Cell_Descriptor{ Callback_get_cell_size user_get_size; Callback_copy_cell user_copy_cell; Callback_restore_cell user_restore_cell; - Callback_init_leaf user_init_leaf; - Callback_free_leaf user_free_leaf; }Scalfmm_Cell_Descriptor; +/** + * @brief This struct contains all the callback affecting leaves + */ +typedef struct User_Scalfmm_Leaf_Descriptor{ + Callback_init_leaf user_init_leaf; + Callback_free_leaf user_free_leaf; + Callback_get_leaf_size user_get_size; + Callback_copy_leaf user_copy_leaf; + Callback_restore_leaf user_restore_leaf; +}Scalfmm_Leaf_Descriptor; /** * @brief This function build the tree. If scalfmm_init has been @@ -228,7 +269,10 @@ typedef struct User_Scalfmm_Cell_Descriptor{ * @param BoxWidth Width of the entire simulation box. * @param BoxCenter Coordinate of the center of the box (ie array) */ -void scalfmm_build_tree(scalfmm_handle handle,int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor); +void scalfmm_build_tree(scalfmm_handle handle,int TreeHeight,double BoxWidth, + double* BoxCenter, + Scalfmm_Cell_Descriptor user_cell_descriptor, + Scalfmm_Leaf_Descriptor user_leaf_descriptor); /** @@ -488,6 +532,15 @@ typedef void (*Callback_P2M)(void* cellData, void * leafData, FSize nbParticles, */ typedef void (*Callback_M2M)(int level, void* parentCell, int childPosition, void* childCell, void* userData); +/** + * @brief Function to be filled by user's M2M + * @param level current level in the tree + * @prama parentCell cell to be filled + * @param userData datas specific to the user's kernel + * @param childCell array of cells to be read + */ +typedef void (*Callback_M2M_Full)(int level, void* parentCell, void* childCell[8], void* userData); + /** * @brief Function to be filled by user's M2L * @param level current level in the tree @@ -529,6 +582,15 @@ typedef void (*Callback_M2LFull)(int level, void* targetCell, const int * neighb */ typedef void (*Callback_L2L)(int level, void* parentCell, int childPosition, void* childCell, void* userData); +/** + * @brief Function to be filled by user's L2L + * @param level current level in the tree + * @prama parentCell cell to be filled + * @param userData datas specific to the user's kernel + * @param childCell array of cells to be read + */ +typedef void (*Callback_L2L_Full)(int level, void* parentCell, void* childCell[8], void* userData); + /** * @brief Function to be filled by user's L2P * @param cellData cell to be read @@ -599,6 +661,29 @@ typedef void (*Callback_P2PInner)(void * targetLeaf,FSize nbParticles, const FSi typedef void (*Callback_P2PSym)(void * targetLeaf, FSize nbParticles, const FSize* particleIndexes, void * sourceLeaf, FSize nbSourceParticles, const FSize* sourceParticleIndexes, void* userData); + +/** + * @brief Function to be filled by user's P2P Remote, the sources will + * be erased after the call, so no need to modify them + * @param targetLeaf ptr to user target leaf + * @param nbParticles number of particle in current leaf + * @param particleIndexes indexes of particles currently computed + * @praram sourceLeaves array of user source target + * @param sourceParticleIndexes array of indexes for each source + * @param sourceNbPart : array containing the number of part for each source + * @param size Number of direct neighbors + * @param userData datas specific to the user's kernel + + * @attention This function will be called in distributed scalfmm + * only, between leaves belonging to diffenrent MPI processus. On ly + * the target leaf should be modified, since we don't send back the + * sources. + */ +typedef void (*Callback_P2PRemote)(void * targetLeaf,FSize nbParticles, const FSize* particleIndexes, + void ** sourceLeaves, + const FSize ** sourceParticleIndexes,FSize * sourceNbPart, + const int * sourcePosition, const int size, void* userData); + /** * @brief Function to be filled by user's method to reset a user's cell * @param level level of the cell. @@ -618,15 +703,18 @@ typedef void (*Callback_apply_on_cell)(int level, long long morton_index, int* t typedef struct User_Scalfmm_Kernel_Descriptor { Callback_P2M p2m; Callback_M2M m2m; + Callback_M2M_Full m2m_full; Callback_M2L m2l; Callback_M2L_Ext m2l_ext; Callback_M2LFull m2l_full; Callback_L2L l2l; + Callback_L2L_Full l2l_full; Callback_L2P l2p; Callback_P2P p2p; Callback_P2PFull p2p_full; Callback_P2PInner p2pinner; Callback_P2PSym p2p_sym; + Callback_P2PRemote p2p_remote; }Scalfmm_Kernel_Descriptor; @@ -662,6 +750,14 @@ void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor */ void scalfmm_execute_fmm(scalfmm_handle Handle); +/** + * @brief This function launch the fmm on the parameters given, but + * only the far field will be evaluated + * @param Handle scalfmm_handle provided by scalfmm_init + */ +void scalfmm_execute_fmm_far_field(scalfmm_handle Handle); + + /** * @brief This function apply the call back on each leaf. Should be * called after insert_parts. @@ -758,8 +854,7 @@ scalfmm_handle scalfmm_init_distributed( scalfmm_kernel_type KernelType,scalfmm_ * once the partitionning done. Can be inserted with no changes. * @param indexesFilled Array that store the global index of each part * in the localArrayFilled. - * @param stride stride between two attributes inside attr. - * @param attr array of attribute to be distributed alongside the positions. + * @param outputNbPoint number of points dedicated to this proc */ void scalfmm_create_local_partition(scalfmm_handle handle, int nbPoints, double * particleXYZ, double ** localArrayFilled, FSize ** indexesFilled, FSize * outputNbPoint); diff --git a/Addons/CKernelApi/Src/FInterEngine.hpp b/Addons/CKernelApi/Src/FInterEngine.hpp index 499e74e1a6fb4942799b36ccc58fd7574c601d95..33b94d42e657e88f5a369f001c918531630ff91e 100644 --- a/Addons/CKernelApi/Src/FInterEngine.hpp +++ b/Addons/CKernelApi/Src/FInterEngine.hpp @@ -83,7 +83,8 @@ public: FScalFMMEngine::Algorithm = algo; } - void build_tree(int TreeHeight, FReal BoxWidth , FReal * BoxCenter,User_Scalfmm_Cell_Descriptor notUsedHere){ + virtual void build_tree(int TreeHeight, FReal BoxWidth , FReal * BoxCenter, + User_Scalfmm_Cell_Descriptor notUsedHere, Scalfmm_Leaf_Descriptor notUsedHereToo){ octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter)); this->matrix = new MatrixKernelClass(); this->kernel = new InterKernel(TreeHeight,BoxWidth,FPoint(BoxCenter),matrix); @@ -115,12 +116,12 @@ public: }else{ if(type==SOURCE){ for(FSize idPart = 0; idPartinsert(FPoint(&XYZ[3*idPart]),FParticleTypeSource,idPart); + octree->insert(FPoint(&XYZ[3*idPart]),FParticleType::FParticleTypeSource,idPart); } FScalFMMEngine::nbPart += NbPositions; }else{ for(FSize idPart = 0; idPartinsert(FPoint(&XYZ[3*idPart]),FParticleTypeTarget,idPart); + octree->insert(FPoint(&XYZ[3*idPart]),FParticleType::FParticleTypeTarget,idPart); } FScalFMMEngine::nbPart += NbPositions; } @@ -138,12 +139,12 @@ public: }else{ if(type==SOURCE){ for(FSize idPart = 0; idPartinsert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleTypeSource,idPart); + octree->insert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleType::FParticleTypeSource,idPart); } FScalFMMEngine::nbPart += NbPositions; }else{ for(FSize idPart = 0; idPartinsert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleTypeTarget,idPart); + octree->insert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleType::FParticleTypeTarget,idPart); } FScalFMMEngine::nbPart += NbPositions; } @@ -738,6 +739,47 @@ public: // } // } + void execute_fmm_far_field(){ + switch(FScalFMMEngine::Algorithm){ + case 0: + { + typedef FFmmAlgorithm AlgoClassSeq; + AlgoClassSeq* algoSeq = new AlgoClassSeq(octree,kernel); + algoSeq->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); + FScalFMMEngine::algoTimer = algoSeq; + FScalFMMEngine::abstrct = algoSeq; + break; + } + case 1: + { + typedef FFmmAlgorithmThread AlgoClassThread; + AlgoClassThread* algoThread = new AlgoClassThread(octree,kernel); + algoThread->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); + FScalFMMEngine::algoTimer = algoThread; + FScalFMMEngine::abstrct = algoThread; + break; + } + case 2: + { + typedef FFmmAlgorithmPeriodic AlgoClassPeriodic; + AlgoClassPeriodic algoPeriod(octree,2); + algoPeriod.setKernel(kernel); + algoPeriod.execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); + break; + } + case 3: + { + typedef FFmmAlgorithmThreadTsm AlgoClassTargetSource; + AlgoClassTargetSource* algoTS = new AlgoClassTargetSource(octree,kernel); + algoTS->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); + FScalFMMEngine::algoTimer = algoTS; + FScalFMMEngine::abstrct = algoTS; + break; + } + default : + std::cout<< "No algorithm found (probably for strange reasons) : "<< FScalFMMEngine::Algorithm <<" exiting" << std::endl; + } + } void execute_fmm(){ switch(FScalFMMEngine::Algorithm){ diff --git a/Addons/CKernelApi/Src/FScalFMMEngine.hpp b/Addons/CKernelApi/Src/FScalFMMEngine.hpp index a397fb7dfebc00b758f150a96ce1f3b20cc132fe..5463357219927d54c795a5177f67bc926b8ddb2b 100644 --- a/Addons/CKernelApi/Src/FScalFMMEngine.hpp +++ b/Addons/CKernelApi/Src/FScalFMMEngine.hpp @@ -95,7 +95,9 @@ public: //by specific Engine //Function about the tree - virtual void build_tree(int TreeHeight,FReal BoxWidth,FReal* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){ + virtual void build_tree(int TreeHeight,FReal BoxWidth,FReal* BoxCenter, + Scalfmm_Cell_Descriptor user_cell_descriptor, + Scalfmm_Leaf_Descriptor user_leaf_descriptor){ FAssertLF(0,"Nothing has been done yet, exiting"); } @@ -178,37 +180,6 @@ public: } - /** Test ... */ - struct RunContainer{ - template< int nbAttributeToInsert,class ContainerClass,class LeafClass, class CellClass> - static void Run(FOctree * octree, - int NbPartToInsert,int * strideForEachAtt, - FReal* rawDatas){ - generic_tree_abstract_insert(octree, - NbPartToInsert,strideForEachAtt,rawDatas); - } - }; - - template - void generic_tree_abstract_insert(FOctree * octree, - int NbPartToInsert,int * strideForEachAtt, - FReal* rawDatas){ - for(FSize idxPart = 0; idxPart pos = FPoint(rawDatas[0],rawDatas[1],rawDatas[2]); - MortonIndex index = octree->getMortonFromPosition(pos); - //Insert with how many attributes ??? - octree->insert(pos,idxPart); - //Get again the container - ContainerClass * containerToFill = octree->getLeafSrc(index);//cannot be nullptr - std::array arrayOfAttribute; - for(int idxAtt = 0; idxAttgetNbParticles(); - containerToFill->remove(&idxToRemove,1); - containerToFill->push(pos,idxPart,arrayOfAttribute); - } - } template void generic_get_forces_xyz(FOctree * octree, @@ -806,6 +777,9 @@ public: virtual void execute_fmm(){ FAssertLF(0,"No kernel set, cannot execute anything, exiting ...\n"); } + virtual void execute_fmm_far_field(){ + FAssertLF(0,"No kernel set, cannot execute anything, exiting ...\n"); + } virtual void intern_dealloc_handle(Callback_free_cell userDeallocator){ FAssertLF(0,"No kernel set, cannot execute anything, exiting ...\n"); @@ -820,15 +794,17 @@ public: * get the time spent in each operator. */ virtual void get_timers(FReal * Timers){ - const FTic * timers = algoTimer->getAllTimers(); - int nbTimers = algoTimer->getNbOfTimerRecorded(); - for(int idTimer = 0; idTimerTimers["P2M"].elapsed(); + Timers[1] = algoTimer->Timers["M2M"].elapsed(); + Timers[2] = algoTimer->Timers["M2L"].elapsed(); + Timers[3] = algoTimer->Timers["L2L"].elapsed(); + Timers[4] = algoTimer->Timers["L2P"].elapsed(); + Timers[5] = algoTimer->Timers["P2P"].elapsed(); + Timers[6] = algoTimer->Timers["NearField"].elapsed(); } virtual int get_nb_timers(){ - return algoTimer->getNbOfTimerRecorded(); + return FAlgorithmTimers::nbTimers; } virtual void set_upper_limit(int upperLimit){ @@ -862,8 +838,11 @@ struct ScalFmmCoreHandle { -extern "C" void scalfmm_build_tree(scalfmm_handle Handle,int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){ - ((ScalFmmCoreHandle *) Handle)->engine->build_tree(TreeHeight,BoxWidth, BoxCenter, user_cell_descriptor); +extern "C" void scalfmm_build_tree(scalfmm_handle Handle,int TreeHeight,double BoxWidth, + double* BoxCenter, + Scalfmm_Cell_Descriptor user_cell_descriptor, + Scalfmm_Leaf_Descriptor user_leaf_descriptor){ + ((ScalFmmCoreHandle *) Handle)->engine->build_tree(TreeHeight,BoxWidth, BoxCenter, user_cell_descriptor, user_leaf_descriptor); } extern "C" void scalfmm_tree_insert_particles(scalfmm_handle Handle, int NbPositions, double * arrayX, double * arrayY, double * arrayZ, @@ -1018,6 +997,12 @@ extern "C" void scalfmm_execute_fmm(scalfmm_handle Handle){ ((ScalFmmCoreHandle * ) Handle)->engine->execute_fmm(); } +//Executing FMM +extern "C" void scalfmm_execute_fmm_far_field(scalfmm_handle Handle){ + ((ScalFmmCoreHandle * ) Handle)->engine->execute_fmm_far_field(); +} + + extern "C" void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor userKernel, void * userDatas){ ((ScalFmmCoreHandle * ) Handle)->engine->user_kernel_config(userKernel,userDatas); } diff --git a/Addons/CKernelApi/Src/FScalfmmApiInit.cpp b/Addons/CKernelApi/Src/FScalfmmApiInit.cpp index 556467a0ad02a0471823022a0250fb6a44073d7a..76074ce6f4d57faa293c4a1badd5a015cbca1835 100644 --- a/Addons/CKernelApi/Src/FScalfmmApiInit.cpp +++ b/Addons/CKernelApi/Src/FScalfmmApiInit.cpp @@ -6,6 +6,15 @@ extern "C" { #include "FInterEngine.hpp" #include "FUserKernelEngine.hpp" + +/** + * Define here static member + */ +Scalfmm_Cell_Descriptor CoreCell::user_cell_descriptor; +template +Scalfmm_Leaf_Descriptor FUserLeafContainer::user_leaf_descriptor; + + extern "C" scalfmm_handle scalfmm_init(/*int TreeHeight,double BoxWidth, double* BoxCenter, */ scalfmm_kernel_type KernelType, @@ -154,6 +163,55 @@ typedef struct FChebCell_struct{ FChebCell * cell; }ChebCellStruct; +typedef struct FChebLeaf_struct{ + //Store a P2PParticleContainer + FP2PParticleContainerIndexed* container; +}ChebLeafStruct; + + +//Initialize leaves +extern "C" ChebLeafStruct * ChebLeafStruct_create(FSize nbPart){ + FP2PParticleContainerIndexed* newCont = new FP2PParticleContainerIndexed(); + newCont->reserve(nbPart); + ChebLeafStruct * newLeaf = new ChebLeafStruct(); + newLeaf->container = newCont; + return newLeaf; +} + +//Delete leaves +extern "C" void ChebLeafStruct_free(void * leafData){ + ChebLeafStruct * leaf = reinterpret_cast(leafData); + delete leaf->container; + delete leaf; +} + +//Fill leaves once partitionning is done +extern "C" void ChebLeafStruct_fill(FSize nbPart, const FSize * idxPart, + long long morton_index, void * leafData, + void * userData){ + UserData * userDataKernel = reinterpret_cast(userData); + ChebLeafStruct * leaf = reinterpret_cast(leafData); + FP2PParticleContainerIndexed* container = leaf->container; + + for(int i=0 ; i pos{userDataKernel->insertedPositions[idxPart[i]*3 + 0], + userDataKernel->insertedPositions[idxPart[i]*3 + 1], + userDataKernel->insertedPositions[idxPart[i]*3 + 2]}; + double phi = userDataKernel->myPhyValues[idxPart[i]]; + container->push(pos,idxPart[i],phi); + } +} + + +extern "C" void ChebLeafStruct_get_back_results(void * leafData, + double ** forceXptr, double ** forceYptr, double ** forceZptr, + double ** potentialsptr){ + ChebLeafStruct * leaf = reinterpret_cast(leafData); + *forceXptr = leaf->container->getForcesX(); + *forceYptr = leaf->container->getForcesY(); + *forceZptr = leaf->container->getForcesZ(); + *potentialsptr = leaf->container->getPotentials(); +} //How to create/destroy cells extern "C" ChebCellStruct * ChebCellStruct_create(long long int inIndex,int * position){ @@ -179,6 +237,8 @@ typedef struct FChebKernel_struct{ FInterpMatrixKernelR * matrix; } ChebKernelStruct; + + //Kernel functions extern "C" ChebKernelStruct * ChebKernelStruct_create(int inTreeHeight, double inBoxWidth, @@ -210,8 +270,30 @@ extern "C" void ChebKernelStruct_free(void *inKernel){ delete reinterpret_cast(inKernel); } +/** +* New one, intended to work with internal FP2PParticleContainer instead of filling a new one +*/ +extern "C" void ChebKernel_P2M(void * leafCell, void * leafData, FSize nbParticles, + const FSize *particleIndexes, void * inKernel){ + //get the real leaf + ChebLeafStruct * leaf = reinterpret_cast(leafData); -extern "C" void ChebKernel_P2M(void * leafCell, FSize nbParticles, const FSize *particleIndexes, void * inKernel){ + //get the real cell struct + ChebCellStruct * realCellStruct = reinterpret_cast(leafCell); + FChebCell * realCell = realCellStruct->cell; + + //Identify thread number + int id_thread = omp_get_thread_num(); + + //get the real chebyshev struct + UserData * userDataKernel = reinterpret_cast(inKernel); + ChebKernelStruct * realKernel = userDataKernel->kernelStruct; + + realKernel->kernel[id_thread]->P2M(realCell, leaf->container); +} + +extern "C" void ChebKernel_P2M_old(void * leafCell, void * leafData, FSize nbParticles, + const FSize *particleIndexes, void * inKernel){ //make temporary array of parts FP2PParticleContainerIndexed* tempContainer = new FP2PParticleContainerIndexed(); tempContainer->reserve(nbParticles); @@ -239,6 +321,7 @@ extern "C" void ChebKernel_P2M(void * leafCell, FSize nbParticles, const FSize * delete tempContainer; } + extern "C" void ChebKernel_M2M(int level, void* parentCell, int childPosition, void *childCell, void *inKernel){ //Get our structures ChebCellStruct * parentCellStruct = reinterpret_cast(parentCell); @@ -297,7 +380,28 @@ extern "C" void ChebKernel_L2L(int level, void* parentCell, int childPosition, v childChebCell->getLocal(0)); } -extern "C" void ChebKernel_L2P(void* leafCell, FSize nbParticles, const FSize* particleIndexes, void* inKernel){ +extern "C" void ChebKernel_L2P(void* leafCell, void * leafData, FSize nbParticles, + const FSize* particleIndexes, void* inKernel){ + //get the real leaf + ChebLeafStruct * leaf = reinterpret_cast(leafData); + + //get the real cell struct + ChebCellStruct * realCellStruct = reinterpret_cast(leafCell); + FChebCell * realCell = realCellStruct->cell; + + //Identify thread number + int id_thread = omp_get_thread_num(); + + //get the real chebyshev struct + UserData * userDataKernel = reinterpret_cast(inKernel); + ChebKernelStruct * realKernel = userDataKernel->kernelStruct; + + realKernel->kernel[id_thread]->L2P(realCell,leaf->container); +} + + +extern "C" void ChebKernel_L2P_old(void* leafCell, void * leafData,FSize nbParticles, + const FSize* particleIndexes, void* inKernel){ //Create temporary FSimpleLeaf FP2PParticleContainerIndexed* tempContainer = new FP2PParticleContainerIndexed(); tempContainer->reserve(nbParticles); @@ -338,9 +442,43 @@ extern "C" void ChebKernel_L2P(void* leafCell, FSize nbParticles, const FSize* p tempContainer=nullptr; } - -void ChebKernel_P2P(FSize nbParticles, const FSize* particleIndexes, const FSize ** sourceParticleIndexes,FSize* sourceNbPart, +void ChebKernel_P2P(void * targetleaf, FSize nbParticles, const FSize* particleIndexes, void ** sourceLeaves, + const FSize ** sourceParticleIndexes, FSize* sourceNbPart, const int * sourcePosition,const int size, void* inKernel){ + //First step, convert the target leaf in a P2P Particle container + ChebLeafStruct * tgtLeaf = reinterpret_cast(targetleaf); + + //Same with the sources leaves + std::vector *> arraySrcLeaves; + arraySrcLeaves.reserve(size); + for(int i=0 ; i(sourceLeaves[i])->container); + }else{ + arraySrcLeaves.push_back(nullptr); + } + } + + //Then call P2P ? + //Identify thread number + int id_thread = omp_get_thread_num(); + + //Get the kernel + ChebKernelStruct * inKernelStruct = reinterpret_cast(inKernel)->kernelStruct; + + //Empty tree coordinate + int coord[3] = {0,0,0}; + + inKernelStruct->kernel[id_thread]->P2P(FTreeCoordinate(coord),tgtLeaf->container,tgtLeaf->container, + arraySrcLeaves.data(),sourcePosition,size); + +} + + +void ChebKernel_P2P_old(void * targetLeaf, FSize nbParticles, const FSize* particleIndexes, + void ** sourceLeaves, + const FSize ** sourceParticleIndexes,FSize* sourceNbPart, + const int * sourcePosition,const int size, void* inKernel){ //Create temporary FSimpleLeaf for target FP2PParticleContainerIndexed* tempContTarget = new FP2PParticleContainerIndexed(); @@ -421,13 +559,48 @@ void ChebKernel_P2P(FSize nbParticles, const FSize* particleIndexes, const FSize delete [] tempContSources; } + +void ChebKernel_P2PRemote(void * targetLeaf,FSize nbParticles, const FSize* particleIndexes, + void ** sourceLeaves, + const FSize ** sourceParticleIndexes,FSize * sourceNbPart, + const int * sourcePosition, const int size, void* inKernel){ + //First step, convert the target leaf in a P2P Particle container + ChebLeafStruct * tgtLeaf = reinterpret_cast(targetLeaf); + + //Same with the sources leaves + std::vector *> arraySrcLeaves; + arraySrcLeaves.reserve(size); + for(int i=0 ; i(sourceLeaves[i])->container); + }else{ + arraySrcLeaves.push_back(nullptr); + } + } + + //Then call P2P ? + //Identify thread number + int id_thread = omp_get_thread_num(); + + //Get the kernel + ChebKernelStruct * inKernelStruct = reinterpret_cast(inKernel)->kernelStruct; + + //Empty tree coordinate + int coord[3] = {0,0,0}; + + inKernelStruct->kernel[id_thread]->P2PRemote(FTreeCoordinate(coord),tgtLeaf->container,tgtLeaf->container, + arraySrcLeaves.data(),sourcePosition,size); + +} + + void ChebCell_reset(int level, long long morton_index, int* tree_position, double* spatial_position, void * userCell,void * inKernel){ ChebCellStruct * cellStruct = reinterpret_cast(userCell); FChebCell* chebCell = cellStruct->cell; chebCell->resetToInitialState(); } -FSize ChebCell_getSize(int level,void * userData, long long morton_index){ +FSize ChebCell_getSize(int level, long long morton_index){ //Create fake one and ask for its size FChebCell* chebCell = new FChebCell(); //then return what size is needed to store a cell @@ -501,4 +674,94 @@ void* ChebCell_restore(int level, void * arrayTobeRead){ return cellStruct; } +/** + * @brief Those fucntion implements the copy,restore and get_size + * functions for leaves + */ +FSize ChebLeaf_getSize(FSize nbPart){ + //Test where we do not use leafData + FP2PParticleContainerIndexed* newCont = new FP2PParticleContainerIndexed(); + newCont->reserve(nbPart); + //fake push empty parts + for(int i=0 ; i pos{0,0,0}; + newCont->push(pos,0,0,0,0,0); + } + + FSize res = newCont->getSavedSize(); + delete newCont; + + return res; +} + +/** + * Copy Order : Positions XYZ, then attributes + */ +void ChebLeaf_copy(FSize nbPart,void * userLeaf, void * memAllocated){ + ChebLeafStruct * tgtLeaf = reinterpret_cast(userLeaf); + FP2PParticleContainerIndexed* container = tgtLeaf->container; + + char * toWrite = reinterpret_cast(memAllocated); + + FSize cursor = 0; + //Loop over dimensions + for(int i=0 ; i<3 ; ++i){ + memcpy(&toWrite[cursor],container->getPositions()[i],nbPart*sizeof(double)); + cursor += nbPart*sizeof(double); + } + + //Then store attributes + //First physical values + memcpy(&toWrite[cursor],container->getPhysicalValuesArray(),sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + //Then fx + memcpy(&toWrite[cursor],container->getForcesXArray(),sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + //Then fy + memcpy(&toWrite[cursor],container->getForcesYArray(),sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + //Then fz + memcpy(&toWrite[cursor],container->getForcesZArray(),sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + + //Finally potentials + memcpy(&toWrite[cursor],container->getPotentialsArray(),sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; +} + +void * ChebLeaf_restore(FSize nbPart,void * memToRead){ + ChebLeafStruct * tgtLeaf = ChebLeafStruct_create(nbPart); + FP2PParticleContainerIndexed* container = tgtLeaf->container; + + char * toRead = reinterpret_cast(memToRead); + + FSize cursor = 0; + + //Loop over dimensions + for(int i=0 ; i<3 ; ++i){ + memcpy(container->getWPositions()[i],&toRead[cursor],nbPart*sizeof(double)); + cursor += nbPart*sizeof(double); + } + + //Then store attributes + //First physical values + memcpy(container->getPhysicalValuesArray(),&toRead[cursor],sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + //Then fx + memcpy(container->getForcesXArray(),&toRead[cursor],sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + //Then fy + memcpy(container->getForcesYArray(),&toRead[cursor],sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + //Then fz + memcpy(container->getForcesZArray(),&toRead[cursor],sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + + //Finally potentials + memcpy(container->getPotentialsArray(),&toRead[cursor],sizeof(double)*nbPart); + cursor += sizeof(double)*nbPart; + + return tgtLeaf; +} + #endif diff --git a/Addons/CKernelApi/Src/FUserKernelDistrEngine.hpp b/Addons/CKernelApi/Src/FUserKernelDistrEngine.hpp index dba12ace23184eb84ebf61a35dea3d788b5049a0..c1f6636340d6eba3cff0f31542af5b9f83d2e0d9 100644 --- a/Addons/CKernelApi/Src/FUserKernelDistrEngine.hpp +++ b/Addons/CKernelApi/Src/FUserKernelDistrEngine.hpp @@ -11,17 +11,21 @@ #include "Utils/FMpi.hpp" #include "FUserKernelEngine.hpp" -#include "BalanceTree/FLeafBalance.hpp" +#include "Utils/FLeafBalance.hpp" #include "Files/FMpiTreeBuilder.hpp" #include "Containers/FVector.hpp" #include "Core/FFmmAlgorithmThreadProc.hpp" class CoreCellDist : public CoreCell, public FAbstractSendable{ int level; - + void * userKernelData; public: - CoreCellDist() : level(-1){ + CoreCellDist() : level(-1),userKernelData(nullptr){ + + } + void init_UserKernelData(void * in){ + this->userKernelData = in; } /** @@ -29,10 +33,10 @@ public: */ template void save(BufferWriterClass& buffer) const{ - FBasicCell::save(); + FBasicCell::save(buffer); buffer << level; if(user_cell_descriptor.user_get_size){ - FSize sizeToSave = user_cell_descriptor.user_get_size(level,CoreCell::getContainer(),getMortonIndex()); + FSize sizeToSave = user_cell_descriptor.user_get_size(level,getMortonIndex(),userKernelData); char * temp = new char[sizeToSave]; user_cell_descriptor.user_copy_cell(CoreCell::getContainer(),sizeToSave,(void *) temp); buffer.write(temp,sizeToSave); @@ -45,10 +49,10 @@ public: */ template void restore(BufferReaderClass& buffer){ - FBasicCell::restore(); + FBasicCell::restore(buffer); buffer >> level; if(user_cell_descriptor.user_restore_cell){ - FSize sizeToSave = user_cell_descriptor.user_get_size(level,CoreCell::getContainer(),getMortonIndex()); + FSize sizeToSave = user_cell_descriptor.user_get_size(level,getMortonIndex(),userKernelData); char * temp = new char[sizeToSave]; buffer.fillArray(temp,sizeToSave); CoreCell::setContainer(user_cell_descriptor.user_restore_cell(level,temp)); @@ -61,7 +65,7 @@ public: */ template void serializeUp(BufferWriterClass& buffer) const { - FSize sizeToSave = user_cell_descriptor.user_get_size(level,CoreCell::getContainer(),getMortonIndex()); + FSize sizeToSave = user_cell_descriptor.user_get_size(level,getMortonIndex(),userKernelData); char * temp = new char[sizeToSave]; user_cell_descriptor.user_copy_cell(CoreCell::getContainer(),sizeToSave,(void *) temp); buffer.write(temp,sizeToSave); @@ -69,7 +73,7 @@ public: } template void serializeDown(BufferWriterClass& buffer) const { - FSize sizeToSave = user_cell_descriptor.user_get_size(level,CoreCell::getContainer(),getMortonIndex()); + FSize sizeToSave = user_cell_descriptor.user_get_size(level,getMortonIndex(),userKernelData); char * temp = new char[sizeToSave]; user_cell_descriptor.user_copy_cell(CoreCell::getContainer(),sizeToSave,(void *) temp); buffer.write(temp,sizeToSave); @@ -77,7 +81,7 @@ public: } template void deserializeUp(BufferReaderClass& buffer) const { - FSize sizeToSave = user_cell_descriptor.user_get_size(level,CoreCell::getContainer(),getMortonIndex()); + FSize sizeToSave = user_cell_descriptor.user_get_size(level,getMortonIndex(),userKernelData); char * temp = new char[sizeToSave]; buffer.fillArray(temp,sizeToSave); CoreCell::setContainer(user_cell_descriptor.user_restore_cell(level,temp)); @@ -86,7 +90,7 @@ public: } template void deserializeDown(BufferReaderClass& buffer) const { - FSize sizeToSave = user_cell_descriptor.user_get_size(level,CoreCell::getContainer(),getMortonIndex()); + FSize sizeToSave = user_cell_descriptor.user_get_size(level,getMortonIndex(),userKernelData); char * temp = new char[sizeToSave]; buffer.fillArray(temp,sizeToSave); CoreCell::setContainer(user_cell_descriptor.user_restore_cell(level,temp)); @@ -99,8 +103,8 @@ public: */ FSize getSavedSize() const { FSize toReturn = user_cell_descriptor.user_get_size(level, - CoreCell::getContainer(), - getMortonIndex()) + getMortonIndex(), + userKernelData) + FBasicCell::getSavedSize() //Size of storage needed for Basic Cell + sizeof(int) //Size of storage needed for this class + sizeof(nullptr); //Size of storage needed for the parent class @@ -108,14 +112,14 @@ public: } FSize getSavedSizeUp() const{ FSize toReturn = user_cell_descriptor.user_get_size(level, - CoreCell::getContainer(), - getMortonIndex()); + getMortonIndex(), + userKernelData); return toReturn; } FSize getSavedSizeDown() const{ FSize toReturn = user_cell_descriptor.user_get_size(level, - CoreCell::getContainer(), - getMortonIndex()); + getMortonIndex(), + userKernelData); return toReturn; } }; @@ -232,13 +236,13 @@ private: } void setNbPartPerProc(FSize nbPart, const FMpi::FComm * comm){ - if(partPerProc.size() < comm->processCount()){ + if(partPerProc.size() < (unsigned) comm->processCount()){ setNbProc(comm->processCount()); } MPI_Allgather(&nbPart, 1, MPI_LONG_LONG, partPerProc.data() , 1, MPI_LONG_LONG, comm->getComm()); } void setOriNbPartPerProc(FSize nbPart, const FMpi::FComm * comm){ - if(oriPartPerProc.size() < comm->processCount()){ + if(oriPartPerProc.size() < (unsigned) comm->processCount()){ setNbProc(comm->processCount()); } MPI_Allgather(&nbPart, 1, MPI_LONG_LONG, oriPartPerProc.data(), 1, MPI_LONG_LONG, comm->getComm()); @@ -440,8 +444,11 @@ public: this->init_cell(); } - void build_tree(int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){ + void build_tree(int TreeHeight,double BoxWidth,double* BoxCenter, + Scalfmm_Cell_Descriptor user_cell_descriptor, + Scalfmm_Leaf_Descriptor user_leaf_descriptor){ CoreCell::Init(user_cell_descriptor); + ContainerClass::Init(user_leaf_descriptor); Parent::treeHeight = TreeHeight; Parent::boxCenter = FPoint(BoxCenter[0],BoxCenter[1],BoxCenter[2]); Parent::boxWidth = BoxWidth; @@ -451,6 +458,10 @@ public: Parent::boxWidthAtLeafLevel = BoxWidth/(2<(BoxCenter)); + //There : for each cell, set a ptr to UserkernelData + octreeDist->forEachCell([&](CoreCellDist * currCell){ + currCell->init_UserKernelData(Parent::getKernelPtr()->getUserKernelDatas()); + }); } void user_kernel_config( Scalfmm_Kernel_Descriptor userKernel, void * userDatas){ @@ -481,11 +492,11 @@ public: //Evaluate Morton Index host.setX(FCoordinateComputer::GetTreeCoordinate(particleXYZ[id*3+0] - this->getBoxCorner().getX(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), this->getTreeHeight())); - host.setX(FCoordinateComputer::GetTreeCoordinate(particleXYZ[id*3+1] - this->getBoxCorner().getX(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), + host.setX(FCoordinateComputer::GetTreeCoordinate(particleXYZ[id*3+1] - this->getBoxCorner().getY(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), this->getTreeHeight())); - host.setX(FCoordinateComputer::GetTreeCoordinate(particleXYZ[id*3+2] - this->getBoxCorner().getX(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), + host.setX(FCoordinateComputer::GetTreeCoordinate(particleXYZ[id*3+2] - this->getBoxCorner().getZ(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), this->getTreeHeight())); - arrayToBeSorted[id].index = host.getMortonIndex(this->getTreeHeight()); + arrayToBeSorted[id].index = host.getMortonIndex(); } // This is the array that will contains our particles. FVector particles; @@ -528,7 +539,6 @@ public: particles.clear(); //Set the bool to true this->alreadyPartionned = true; - } void generic_partition(FSize nbThings, size_t stride, void * arrayOfThing, void ** newArray){ @@ -626,7 +636,7 @@ public: if(!(currCell->getContainer())){ FTreeCoordinate currCoord = currCell->getCoordinate(); int arrayCoord[3] = {currCoord.getX(),currCoord.getY(),currCoord.getZ()}; - MortonIndex currMorton = currCoord.getMortonIndex(currLevel); + MortonIndex currMorton = currCoord.getMortonIndex(); double position[3]; FPoint boxC = this->getBoxCorner(); position[0] = boxC.getX() + currCoord.getX()*boxwidth/double(1<setContainer(CoreCell::GetInit()(currLevel,currMorton,arrayCoord,position,generic_ptr)); } }); + if(ContainerClass::GetInitLeaf()){ + octreeDist->forEachCellLeaf([&](CoreCell * currCell, LeafClass * leaf){ + FTreeCoordinate currCoord = currCell->getCoordinate(); + int currLevel = octreeDist->getHeight()-1; + MortonIndex currMorton = currCoord.getMortonIndex(); + double position[3]; + FPoint boxC = this->getBoxCorner(); + position[0] = boxC.getX() + currCoord.getX()*boxwidth/double(1<getSrc()->setContainer(ContainerClass::GetInitLeaf()(currLevel, + leaf->getSrc()->getNbParticles(), + leaf->getSrc()->getIndexes().data(), currMorton, + position, currCell->getContainer(), this->kernel->getUserKernelDatas())); + }); + } + } + + void apply_on_cell(Callback_apply_on_cell function){ + double boxwidth = octreeDist->getBoxWidth(); + //apply user function reset on each user's cell + octreeDist->forEachCellWithLevel([&](CoreCell * currCell,const int currLevel){ + if(currCell->getContainer()){ + FTreeCoordinate currCoord = currCell->getCoordinate(); + int arrayCoord[3] = {currCoord.getX(),currCoord.getY(),currCoord.getZ()}; + MortonIndex currMorton = currCoord.getMortonIndex(); + double position[3]; + FPoint boxC = this->getBoxCorner(); + position[0] = boxC.getX() + currCoord.getX()*boxwidth/double(1<getContainer(),kernel->getUserKernelDatas()); + } + }); } void apply_on_each_leaf(Callback_apply_on_leaf function){ @@ -656,7 +700,7 @@ public: typedef FFmmAlgorithmThreadProc AlgoProcClass; AlgoProcClass * algoProc = new AlgoProcClass(*comm,octreeDist,kernel); FScalFMMEngine::algoTimer = algoProc; - algoProc->execute(); + algoProc->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P | FFmmP2P); break; } default: @@ -664,6 +708,25 @@ public: } } + void execute_fmm_far_field(){ + FAssertLF(octreeDist, + "No Tree set, please use scalfmm_user_kernel_config before calling the execute routine ... Exiting \n"); + //Only one config shall work , so let's use it + switch(FScalFMMEngine::Algorithm){ + case 5: + { + typedef FFmmAlgorithmThreadProc AlgoProcClass; + AlgoProcClass * algoProc = new AlgoProcClass(*comm,octreeDist,kernel); + FScalFMMEngine::algoTimer = algoProc; + algoProc->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); + break; + } + default: + break; + } + } + + void free_cell(Callback_free_cell user_cell_deallocator){ octreeDist->forEachCell([&](CoreCellDist * currCell){ if(currCell->getContainer()){ diff --git a/Addons/CKernelApi/Src/FUserKernelEngine.hpp b/Addons/CKernelApi/Src/FUserKernelEngine.hpp index 300bceb954a17414a48ad4d6ae9202c6a21db941..e01a8db0131bdbf7f82282f4e10e00e1fc6daaeb 100644 --- a/Addons/CKernelApi/Src/FUserKernelEngine.hpp +++ b/Addons/CKernelApi/Src/FUserKernelEngine.hpp @@ -49,15 +49,6 @@ public: return user_cell_descriptor.user_free_cell; } - static Callback_init_leaf GetInitLeaf(){ - return user_cell_descriptor.user_init_leaf; - } - - static Callback_free_leaf GetFreeLeaf(){ - return user_cell_descriptor.user_free_leaf; - } - - CoreCell() : userData(nullptr) { } @@ -89,13 +80,8 @@ public: return nullptr; //pareil que userdata, finalement } } - }; -/** - * Define here static member - */ -Scalfmm_Cell_Descriptor CoreCell::user_cell_descriptor; /** * This class simply call the function pointers from Scalfmm_Kernel_Descriptor. @@ -123,10 +109,22 @@ public: /** Do nothing */ virtual void M2M(CellClass* const FRestrict cell, const CellClass*const FRestrict *const FRestrict children, const int level) { - if(kernel.m2m){ - for(int idx = 0 ; idx < 8 ; ++idx){ + if(kernel.m2m_full){ + std::vector userCellArray; + for(int idx=0 ;idx<8 ; ++idx){ if( children[idx] ){ - kernel.m2m(level, cell->getContainer(), idx, children[idx]->getContainer(), userData); + userCellArray.push_back(children[idx]->getContainer()); + }else{ + userCellArray.push_back(nullptr); + } + } + kernel.m2m_full(level, cell->getContainer(), userCellArray.data(), userData); + }else{ + if(kernel.m2m){ + for(int idx = 0 ; idx < 8 ; ++idx){ + if( children[idx] ){ + kernel.m2m(level, cell->getContainer(), idx, children[idx]->getContainer(), userData); + } } } } @@ -144,8 +142,7 @@ public: } kernel.m2l_full(level,cell->getContainer(),neighborPositions,size,userCellArray.data(),userData); FAssertLF("m2l_full temporary disabled ...\n"); - } - else{ + }else{ if(kernel.m2l){ for(int idx = 0 ; idx < size ; ++idx){ const int idxNeigh = neighborPositions[idx]; @@ -156,11 +153,26 @@ public: } /** Do nothing */ - virtual void L2L(const CellClass* const FRestrict cell, CellClass* FRestrict *const FRestrict children, const int level) { - if(kernel.l2l){ - for(int idx = 0 ; idx < 8 ; ++idx){ - if( children[idx] ){ - kernel.l2l(level, cell->getContainer(), idx, children[idx]->getContainer(), userData); + virtual void L2L(const CellClass* const FRestrict cell, + CellClass* FRestrict *const FRestrict children, const int level) { + if(kernel.l2l_full){ + std::vector userCellArray; + std::cout<<"Children array is good ?\t"<getContainer()); + }else{ + userCellArray.push_back(nullptr); + } + } + kernel.l2l_full(level, cell->getContainer(), userCellArray.data(), userData); + }else{ + if(kernel.l2l){ + for(int idx = 0 ; idx < 8 ; ++idx){ + if( children[idx] ){ + kernel.l2l(level, cell->getContainer(), idx, children[idx]->getContainer(), userData); + } } } } @@ -181,12 +193,13 @@ public: // } } - virtual void P2P(const FTreeCoordinate& inLeafPosition, ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources, ContainerClass* const neighbors[],const int sourcePosition[], const int size){ - if(kernel.p2pinner) kernel.p2pinner(targets->getContainer(),targets->getNbParticles(), targets->getIndexes().data(), userData); - + if(kernel.p2pinner){ + kernel.p2pinner(targets->getContainer(),targets->getNbParticles(), targets->getIndexes().data(), userData); + //std::cout<<"Inner used\n"; + } if(kernel.p2p_full){ //Create the arrays of size and indexes FSize * nbPartPerNeighbors = new FSize[size]; @@ -202,12 +215,14 @@ public: delete [] nbPartPerNeighbors; delete [] indicesPerNeighbors; delete [] arrayOfUserContainer; + // std::cout<<"P2PFull used\n"; } if(kernel.p2p_sym){ for(int idx = 0 ; ((idx < size) && (sourcePosition[idx] < 14)) ; ++idx){ kernel.p2p_sym(targets->getContainer(),targets->getNbParticles(), targets->getIndexes().data(), neighbors[idx]->getContainer(),neighbors[idx]->getNbParticles(), neighbors[idx]->getIndexes().data(), userData); } + // std::cout<<"P2PSym used\n"; } else{ if(kernel.p2p){ @@ -215,14 +230,33 @@ public: kernel.p2p(targets->getContainer(),targets->getNbParticles(), targets->getIndexes().data(), neighbors[idx]->getContainer(),neighbors[idx]->getNbParticles(), neighbors[idx]->getIndexes().data(), userData); } + // std::cout<<"P2P used\n"; } } } - /** Do nothing */ - virtual void P2PRemote(const FTreeCoordinate& , - ContainerClass* const FRestrict , const ContainerClass* const FRestrict , - ContainerClass const *const *, const int *, const int ){ + virtual void P2PRemote(const FTreeCoordinate& inLeafPosition, + ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources, + const ContainerClass* const neighbors[],const int sourcePosition[], const int size){ + if(kernel.p2p_remote){ + //Create the arrays of size and indexes + FSize * nbPartPerNeighbors = new FSize[size]; + const FSize ** indicesPerNeighbors = new const FSize*[size]; + //create artificial array of void * : + void ** arrayOfUserContainer = new void *[size]; + for(int idx=0 ; idxgetNbParticles(); + indicesPerNeighbors[idx] = neighbors[idx]->getIndexes().data(); + arrayOfUserContainer[idx] = neighbors[idx]->getContainer(); + } + kernel.p2p_remote(targets->getContainer(),targets->getNbParticles(),targets->getIndexes().data(),arrayOfUserContainer, + indicesPerNeighbors,nbPartPerNeighbors,sourcePosition,size,userData); + delete [] nbPartPerNeighbors; + delete [] indicesPerNeighbors; + delete [] arrayOfUserContainer; + }else{ + std::cout<<"Warning, MPI used but no P2P Remote set\n"; + } } //Getter @@ -290,9 +324,6 @@ protected: OctreeClass* getTree() const { return octree; } - CoreKernelClass * getKernelPtr() const { - return kernel; - } public: @@ -319,14 +350,21 @@ public: } } + CoreKernelClass * getKernelPtr() { + return kernel; + } + virtual void user_kernel_config( Scalfmm_Kernel_Descriptor userKernel, void * userDatas){ if(!kernel){ kernel = new CoreKernelClass(userKernel,userDatas); } } - virtual void build_tree(int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){ + virtual void build_tree(int TreeHeight,double BoxWidth,double* BoxCenter, + Scalfmm_Cell_Descriptor user_cell_descriptor, + Scalfmm_Leaf_Descriptor user_leaf_descriptor){ CoreCell::Init(user_cell_descriptor); + ContainerClass::Init(user_leaf_descriptor); this->treeHeight = TreeHeight; this->boxCenter = FPoint(BoxCenter[0],BoxCenter[1],BoxCenter[2]); this->boxWidth = BoxWidth; @@ -338,14 +376,14 @@ public: this->octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter)); } - void apply_on_cell(Callback_apply_on_cell function){ + virtual void apply_on_cell(Callback_apply_on_cell function){ double boxwidth = octree->getBoxWidth(); //apply user function reset on each user's cell octree->forEachCellWithLevel([&](CoreCell * currCell,const int currLevel){ if(currCell->getContainer()){ FTreeCoordinate currCoord = currCell->getCoordinate(); int arrayCoord[3] = {currCoord.getX(),currCoord.getY(),currCoord.getZ()}; - MortonIndex currMorton = currCoord.getMortonIndex(currLevel); + MortonIndex currMorton = currCoord.getMortonIndex(); double position[3]; position[0] = boxCorner.getX() + currCoord.getX()*boxwidth/double(1<insert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleTypeSource,idPart); + octree->insert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleType::FParticleTypeSource,idPart); } FScalFMMEngine::nbPart += NbPositions; }else{ for(FSize idPart = 0; idPartinsert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleTypeTarget,idPart); + octree->insert(FPoint(X[idPart],Y[idPart],Z[idPart]),FParticleType::FParticleTypeTarget,idPart); } FScalFMMEngine::nbPart += NbPositions; } @@ -388,12 +426,12 @@ public: }else{ if(type==SOURCE){ for(FSize idPart = 0; idPartinsert(FPoint(&XYZ[3*idPart]),FParticleTypeSource,idPart); + octree->insert(FPoint(&XYZ[3*idPart]),FParticleType::FParticleTypeSource,idPart); } FScalFMMEngine::nbPart += NbPositions; }else{ for(FSize idPart = 0; idPartinsert(FPoint(&XYZ[3*idPart]),FParticleTypeTarget,idPart); + octree->insert(FPoint(&XYZ[3*idPart]),FParticleType::FParticleTypeTarget,idPart); } FScalFMMEngine::nbPart += NbPositions; } @@ -491,7 +529,7 @@ public: if(!(currCell->getContainer())){ FTreeCoordinate currCoord = currCell->getCoordinate(); int arrayCoord[3] = {currCoord.getX(),currCoord.getY(),currCoord.getZ()}; - MortonIndex currMorton = currCoord.getMortonIndex(currLevel); + MortonIndex currMorton = currCoord.getMortonIndex(); double position[3]; position[0] = boxCorner.getX() + currCoord.getX()*boxwidth/double(1<forEachCellLeaf([&](CoreCell * currCell, LeafClass * leaf){ - FTreeCoordinate currCoord = currCell->getCoordinate(); - int currLevel = octree->getHeight()-1; - MortonIndex currMorton = currCoord.getMortonIndex(currLevel); - double position[3]; - position[0] = boxCorner.getX() + currCoord.getX()*boxwidth/double(1<getSrc()->setContainer(CoreCell::GetInitLeaf()(currLevel,leaf->getSrc()->getNbParticles(), - leaf->getSrc()->getIndexes().data(), currMorton, - position, currCell->getContainer(), this->kernel->getUserKernelDatas())); - }); - + if(ContainerClass::GetInitLeaf()){ + octree->forEachCellLeaf([&](CoreCell * currCell, LeafClass * leaf){ + FTreeCoordinate currCoord = currCell->getCoordinate(); + int currLevel = octree->getHeight()-1; + MortonIndex currMorton = currCoord.getMortonIndex(); + double position[3]; + position[0] = boxCorner.getX() + currCoord.getX()*boxwidth/double(1<getSrc()->setContainer(ContainerClass::GetInitLeaf()(currLevel, + leaf->getSrc()->getNbParticles(), + leaf->getSrc()->getIndexes().data(), currMorton, + position, currCell->getContainer(), this->kernel->getUserKernelDatas())); + }); + } } void free_cell(Callback_free_cell user_cell_deallocator, Callback_free_leaf free_leaf){ - octree->forEachCellLeaf([&](CoreCell * currCell, LeafClass * leaf){ - free_leaf(currCell->getContainer(),leaf->getSrc()->getNbParticles(), leaf->getSrc()->getIndexes().data(), - leaf->getSrc()->getContainer(),this->kernel->getUserKernelDatas()); - }); + if(free_leaf){ + octree->forEachCellLeaf([&](CoreCell * currCell, LeafClass * leaf){ + free_leaf(currCell->getContainer(),leaf->getSrc()->getNbParticles(), leaf->getSrc()->getIndexes().data(), + leaf->getSrc()->getContainer(),this->kernel->getUserKernelDatas()); + }); + } octree->forEachCell([&](CoreCell * currCell){ if(currCell->getContainer()){ user_cell_deallocator(currCell->getContainer()); @@ -667,14 +709,77 @@ public: if(octree->getHeight() == 2){ (FScalFMMEngine::abstrct)->execute(FFmmP2P); }else{ - (FScalFMMEngine::abstrct)->execute(); + (FScalFMMEngine::abstrct)->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P | FFmmP2P); } } } } + virtual void execute_fmm_far_field(){ + FAssertLF(kernel,"No kernel set, please use scalfmm_user_kernel_config before calling the execute routine ... Exiting \n"); + switch(FScalFMMEngine::Algorithm){ + case 0: + { + typedef FFmmAlgorithm AlgoClassSeq; + AlgoClassSeq * algoSeq = new AlgoClassSeq(octree,kernel); + FScalFMMEngine::algoTimer = algoSeq; + FScalFMMEngine::abstrct = algoSeq; + //algoSeq->execute(); will be done later + break; + } + case 1: + { + typedef FFmmAlgorithmThread AlgoClassThread; + AlgoClassThread* algoThread = new AlgoClassThread(octree,kernel); + FScalFMMEngine::algoTimer = algoThread; + FScalFMMEngine::abstrct = algoThread; + //algoThread->execute(); will be done later + break; + } + case 2: + { + typedef FFmmAlgorithmPeriodic AlgoClassPeriodic; + AlgoClassPeriodic algoPeriod(octree,2); + algoPeriod.setKernel(kernel); + algoPeriod.execute(); + break; + } + case 3: + { + typedef FFmmAlgorithmThreadTsm AlgoClassTargetSource; + AlgoClassTargetSource* algoTS = new AlgoClassTargetSource(octree,kernel); + FScalFMMEngine::algoTimer = algoTS; + FScalFMMEngine::abstrct = algoTS; + //algoTS->execute(); will be done later + break; + } + default : + std::cout<< "No algorithm found (probably for strange reasons) : "<< FScalFMMEngine::Algorithm <<" exiting" << std::endl; + } + + if (FScalFMMEngine::Algorithm != 2){ + if(upperLimit != 2){ + (FScalFMMEngine::abstrct)->execute(FFmmP2M | FFmmM2M | FFmmM2L, upperLimit, treeHeight); + printf("\tUpPass finished\n"); + internal_M2L(); + printf("\tStrange M2L finished\n"); + (FScalFMMEngine::abstrct)->execute(FFmmL2L | FFmmL2P, upperLimit, treeHeight); + printf("\tDownPass finished\n"); + } + else{ + if(octree->getHeight() == 2){ + //(FScalFMMEngine::abstrct)->execute(FFmmP2P); + std::cout<<"Nothing to be done\n"; + }else{ + (FScalFMMEngine::abstrct)->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); + } + } + } + } + + virtual void intern_dealloc_handle(Callback_free_cell userDeallocator){ - free_cell(userDeallocator, CoreCell::GetFreeLeaf()); + free_cell(userDeallocator, ContainerClass::GetFreeLeaf()); } }; diff --git a/Addons/CKernelApi/Src/FUserLeafContainer.hpp b/Addons/CKernelApi/Src/FUserLeafContainer.hpp index 39ddee33f11affb026cca908ef682aecaf1dfdd5..f0a7bb7a01469852adbb246ad42c82fcac4b78c1 100644 --- a/Addons/CKernelApi/Src/FUserLeafContainer.hpp +++ b/Addons/CKernelApi/Src/FUserLeafContainer.hpp @@ -36,7 +36,15 @@ class FUserLeafContainer : public FP2PParticleContainerIndexed{ void * userAttributes; + static Scalfmm_Leaf_Descriptor user_leaf_descriptor; + using Parent = FP2PParticleContainerIndexed; + public: + + static void Init(Scalfmm_Leaf_Descriptor leaf_descriptor){ + user_leaf_descriptor = leaf_descriptor; + } + FUserLeafContainer(const FUserLeafContainer&) = delete; FUserLeafContainer& operator =(const FUserLeafContainer&) = delete; @@ -51,6 +59,65 @@ public: return userAttributes; } + static Callback_init_leaf GetInitLeaf(){ + return user_leaf_descriptor.user_init_leaf; + } + + static Callback_free_leaf GetFreeLeaf(){ + return user_leaf_descriptor.user_free_leaf; + } + + /** + * @brief Functions to deal with serialization. + * + */ + template + void save(BufferWriterClass& buffer) const{ + Parent::template save<>(buffer); + if(user_leaf_descriptor.user_copy_leaf){ + FSize nbPart = Parent::getNbParticles(); + FSize sizeToSave = user_leaf_descriptor.user_get_size(nbPart); + char * temp = new char[sizeToSave]; + user_leaf_descriptor.user_copy_leaf(nbPart,getContainer(),temp); + buffer.write(temp,sizeToSave); + delete [] temp; + }else{ + std::cout<<"No user_copy_leaf function set\nExiting\n"; + exit(0); + } + } + template + void restore(BufferReaderClass& buffer){ + Parent::template restore<>(buffer); + if(user_leaf_descriptor.user_restore_leaf){ + FSize nbPart = Parent::getNbParticles(); + FSize sizeToSave = user_leaf_descriptor.user_get_size(nbPart); + + char * temp = new char[sizeToSave]; + buffer.fillArray(temp,sizeToSave); + this->setContainer(user_leaf_descriptor.user_restore_leaf(nbPart,temp)); + delete [] temp; + }else{ + std::cout<<"No user_restore_leaf function set\nExiting\n"; + exit(0); + } + } + + FSize getSavedSize() const { + //Size of internal datas + FSize res = Parent::getSavedSize(); + FSize userSize = 0; + if(!user_leaf_descriptor.user_get_size){ + std::cout<<"No get_save_size function set\nExiting\n"; + exit(0); + }else{ + FSize nbPart = Parent::getNbParticles(); + userSize = user_leaf_descriptor.user_get_size(nbPart); + res += userSize; + } + + return res; + } }; diff --git a/Addons/CKernelApi/Tests/testChebInterface.c b/Addons/CKernelApi/Tests/testChebInterface.c index ec282ea526a68c20df1c086a8e01d797c52c9d4e..00c9f42f664437f0658f4a92b43382acdf9260d7 100644 --- a/Addons/CKernelApi/Tests/testChebInterface.c +++ b/Addons/CKernelApi/Tests/testChebInterface.c @@ -2,6 +2,7 @@ #include #include #include +#include //For timing monitoring #include "Timers.h" @@ -35,17 +36,14 @@ void cheb_free_cell(void * inCell){ */ void * cheb_init_leaf(int level, FSize nbParts, const FSize * idxParts, long long morton_index, double center[3], void * cellDatas, void * userDatas){ - //Do nothing - int * A = malloc(sizeof(double) * nbParts); - return A; + return ChebLeafStruct_create(nbParts); } /** * No need for leaf function */ void cheb_free_leaf(void * cellDatas, FSize nbParts, const FSize * idxParts, void * leafData, void * userDatas){ - free(leafData); - //Do nothing + ChebLeafStruct_free(leafData); } /** @@ -54,7 +52,7 @@ void cheb_free_leaf(void * cellDatas, FSize nbParts, const FSize * idxParts, voi */ void cheb_p2m(void* cellData, void * leafData, FSize nbParticlesInLeaf, const FSize* particleIndexes, void* userData){ - ChebKernel_P2M(cellData,nbParticlesInLeaf,particleIndexes,userData); + ChebKernel_P2M(cellData,leafData,nbParticlesInLeaf,particleIndexes,userData); } void cheb_m2m(int level, void* parentCell, int childPosition, void* childCell, void* userData){ @@ -70,13 +68,14 @@ void cheb_l2l(int level, void* parentCell, int childPosition, void* childCell, } void cheb_l2p(void* leafCell, void * leafData, FSize nbParticles, const FSize* particleIndexes, void* userData){ - ChebKernel_L2P( leafCell, nbParticles, particleIndexes, userData); + ChebKernel_L2P( leafCell, leafData,nbParticles, particleIndexes, userData); } void cheb_p2pFull(void * targetLeaf, FSize nbParticles, const FSize* particleIndexes, void ** sourceLeaves, const FSize ** sourceParticleIndexes, FSize* sourceNbPart,const int * sourcePosition, const int size, void* userData) { - ChebKernel_P2P(nbParticles, particleIndexes, sourceParticleIndexes, sourceNbPart,sourcePosition,size, + printf("NOPE\n"); + ChebKernel_P2P(targetLeaf,nbParticles, particleIndexes, sourceLeaves, sourceParticleIndexes, sourceNbPart,sourcePosition,size, userData); } @@ -86,15 +85,46 @@ void cheb_resetCell(int level, long long morton_index, int* tree_position, } /** - * This function is mainly a display of its args... + * @brief From this point, the scalfmm leaves own the indexes, and + * each proc have its part partitionned, so we just need to copy our + * physical values (Vin) inside each leaf. */ -void on_leaf(int level, FSize nbParts, const FSize * idxParts, long long morton_index, double center[3], - void * cellDatas, void * leafData, void * userDatas){ - /* printf("I'm leaf at %lld pos, of center [%e %e %e], containing %lld parts\n", */ - /* morton_index,center[0],center[1],center[2],nbParts); */ +void fill_leaf_container(int level, FSize nbParts, const FSize * idxParts, + long long morton_index, double center[3], + void * cellDatas,void * leafData, void * userDatas){ + ChebLeafStruct_fill(nbParts,idxParts,morton_index,leafData,userDatas); } +/** + * @brief this function store the results gathered across the leaves + * to store it inside force computed arrays. + */ +void get_results_from_leaves(int level, FSize nbParts, const FSize * idxParts, long long morton_index, double center[3], + void * cellDatas, void * leafData, void * userDatas){ + UserData * ptrToUserData = (UserData*) userDatas; + + double * forceX = NULL; + double ** forceXPtr = &forceX; + double * forceY = NULL; + double ** forceYPtr = &forceY; + double * forceZ = NULL; + double ** forceZPtr = &forceZ; + double * potentials = NULL; + double ** potPtr = &potentials; + + ChebLeafStruct_get_back_results(leafData,forceXPtr,forceYPtr,forceZPtr,potPtr); + + for(int i=0 ; iforcesComputed[0][3*idx+0] = forceX[i]; + ptrToUserData->forcesComputed[0][3*idx+1] = forceY[i]; + ptrToUserData->forcesComputed[0][3*idx+2] = forceZ[i]; + ptrToUserData->potentials[0][idx] = potentials[i]; + } +} /** * @brief Do everything @@ -158,20 +188,24 @@ int main(int argc, char ** av){ struct User_Scalfmm_Cell_Descriptor cellDescriptor; cellDescriptor.user_init_cell = cheb_init_cell; cellDescriptor.user_free_cell = cheb_free_cell; - cellDescriptor.user_init_leaf = cheb_init_leaf; - cellDescriptor.user_free_leaf = cheb_free_leaf; + struct User_Scalfmm_Leaf_Descriptor user_descr_leaf; + user_descr_leaf.user_init_leaf = cheb_init_leaf; + user_descr_leaf.user_free_leaf = cheb_free_leaf; + //should not be checked, but nullify just in case. + user_descr_leaf.user_get_size = NULL; + user_descr_leaf.user_copy_leaf = NULL; + user_descr_leaf.user_restore_leaf = NULL; //Struct for ref cheb kernel struct User_Scalfmm_Cell_Descriptor user_descr; user_descr.user_init_cell = NULL; user_descr.user_free_cell = NULL; - // Init tree and cell printf("Building the tree and Initizalizing the cells:\n"); - scalfmm_build_tree(handle,treeHeight, boxWidth, boxCenter, cellDescriptor); - scalfmm_build_tree(handle_ref,treeHeight, boxWidth, boxCenter, user_descr); + scalfmm_build_tree(handle_ref,treeHeight, boxWidth, boxCenter, user_descr , user_descr_leaf); + scalfmm_build_tree(handle,treeHeight, boxWidth, boxCenter, cellDescriptor,user_descr_leaf); //Once is the tree built, one must set the kernel before inserting particles @@ -179,15 +213,17 @@ int main(int argc, char ** av){ struct User_Scalfmm_Kernel_Descriptor kernel; kernel.p2m = cheb_p2m; kernel.m2m = cheb_m2m; - //init the other to NULL - kernel.m2l = NULL; kernel.m2l_full = cheb_m2l_full; kernel.l2l = cheb_l2l; kernel.l2p = cheb_l2p; - kernel.p2p_sym = NULL; kernel.p2p_full = cheb_p2pFull; + //init the other to NULL + kernel.m2l = NULL; + kernel.p2p_sym = NULL; kernel.p2pinner = NULL; kernel.p2p = NULL; + kernel.m2m_full = NULL; + kernel.l2l_full = NULL; //Set my datas UserData userDatas; @@ -247,15 +283,16 @@ int main(int argc, char ** av){ while(itepotentials[j][idxParts[i]]; + /* for( i=0 ; ipotentials[j][idxParts[i]]; */ + /* } */ + /* ptrToUserData->totalEnergy += pot*(ptrToUserData->myPhyValues[idxParts[i]]); */ + /* } */ + + if(leafData){ + double * forceX = NULL; + double ** forceXPtr = &forceX; + double * forceY = NULL; + double ** forceYPtr = &forceY; + double * forceZ = NULL; + double ** forceZPtr = &forceZ; + double * potentials = NULL; + double ** potPtr = &potentials; + + ChebLeafStruct_get_back_results(leafData,forceXPtr,forceYPtr,forceZPtr,potPtr); + double pot = 0; + + for(int i=0 ; itotalEnergy += pot*(ptrToUserData->myPhyValues[idxParts[i]]); } - /* printf("I'm leaf at %lld pos, of center [%e %e %e], containing %lld parts\n", */ /* morton_index,center[0],center[1],center[2],nbParts); */ @@ -177,19 +257,30 @@ int main(int argc, char ** argv){ cellDescriptor.user_copy_cell = cheb_copy_cell; cellDescriptor.user_restore_cell = cheb_restore_cell; + struct User_Scalfmm_Leaf_Descriptor leafDecriptor; + leafDecriptor.user_init_leaf = cheb_init_leaf; + leafDecriptor.user_free_leaf = cheb_free_leaf; + leafDecriptor.user_get_size = cheb_get_leaf_size; + leafDecriptor.user_copy_leaf = cheb_copy_leaf; + leafDecriptor.user_restore_leaf = cheb_restore_leaf; + //Set our callbacks struct User_Scalfmm_Kernel_Descriptor kernel; kernel.p2m = cheb_p2m; kernel.m2m = cheb_m2m; + kernel.m2m_full = NULL; //init the other to NULL kernel.m2l = NULL; + kernel.m2l_ext = NULL; kernel.m2l_full = cheb_m2l_full; kernel.l2l = cheb_l2l; + kernel.l2l_full = NULL; kernel.l2p = cheb_l2p; kernel.p2p_sym = NULL; kernel.p2p_full = cheb_p2pFull; kernel.p2pinner = NULL; kernel.p2p = NULL; + kernel.p2p_remote = cheb_p2p_remote; //Set my datas UserData userDatas; @@ -197,7 +288,8 @@ int main(int argc, char ** argv){ //Give ScalFMM the datas before calling fmm (this will set as well the kernel) scalfmm_user_kernel_config(Handle,kernel,&userDatas); - scalfmm_build_tree(Handle,treeHeight, boxWidth, boxCenter, cellDescriptor); + scalfmm_build_tree(Handle,treeHeight, boxWidth, boxCenter, + cellDescriptor, leafDecriptor); printf("Tree built.\n"); double * outputArray; //Will be allocated inside create_local_partition @@ -250,14 +342,18 @@ int main(int argc, char ** argv){ printf("Insertion done, I'm process %d, and have inserted %lld parts.\n",my_rank,outputNbPoint); + //Asking ScalFMM to partition physicalValues too scalfmm_generic_partition(Handle,nbPart,sizeof(physicalValues[0]),physicalValues,outputPhyValPtr); - printf("[%d] Generic Partition Done ! \n",my_rank); userDatas.myPhyValues = outputPhyVal; + //There we used a for each leaf method to initialize our leaf containers. + scalfmm_apply_on_leaf(Handle,fill_leaf_container); + + //Execution !! - scalfmm_execute_fmm(Handle); + scalfmm_execute_fmm_far_field(Handle); scalfmm_apply_on_leaf(Handle,on_leaf); diff --git a/Addons/CKernelApi/Tests/testSphereElectro.c b/Addons/CKernelApi/Tests/testSphereElectro.c index 73da7fee2461a13249f2ecba9b7cdd209d272a09..37e7c63ea6f07868cbbcc2cdaa363f2338af25b4 100644 --- a/Addons/CKernelApi/Tests/testSphereElectro.c +++ b/Addons/CKernelApi/Tests/testSphereElectro.c @@ -162,10 +162,18 @@ int main(int argc, char ** av){ struct User_Scalfmm_Cell_Descriptor user_descr; user_descr.user_init_cell = NULL; user_descr.user_free_cell = NULL; + struct User_Scalfmm_Leaf_Descriptor user_descr_leaf; + user_descr_leaf.user_init_leaf = NULL; + user_descr_leaf.user_free_leaf = NULL; + user_descr_leaf.user_get_size = NULL; + user_descr_leaf.user_copy_leaf = NULL; + user_descr_leaf.user_restore_leaf = NULL; + //Set algorithm to source target scalfmm_algorithm_config(handle,source_target); //Build the tree - scalfmm_build_tree(handle,treeHeight, boxWidth, boxCenter, user_descr); + scalfmm_build_tree(handle,treeHeight, boxWidth, boxCenter, + user_descr, user_descr_leaf); //Insert Sources and targets scalfmm_tree_insert_particles_xyz(handle,nbPartSource,sourceXYZ,SOURCE); diff --git a/Addons/CKernelApi/Tests/testUseNewApi.c b/Addons/CKernelApi/Tests/testUseNewApi.c index ce5ecca95eb32b27cdd95631efc22ec6b5819c4d..963f5e76e452166acdcea4fe0a54d27730cdf8f5 100644 --- a/Addons/CKernelApi/Tests/testUseNewApi.c +++ b/Addons/CKernelApi/Tests/testUseNewApi.c @@ -32,8 +32,14 @@ int main(int argc, char ** av){ struct User_Scalfmm_Cell_Descriptor user_descr; user_descr.user_init_cell = NULL; user_descr.user_free_cell = NULL; - - scalfmm_build_tree(handle,TreeHeight,boxWidth,boxCenter,user_descr); + struct User_Scalfmm_Leaf_Descriptor user_descr_leaf; + user_descr_leaf.user_init_leaf = NULL; + user_descr_leaf.user_free_leaf = NULL; + user_descr_leaf.user_get_size = NULL; + user_descr_leaf.user_copy_leaf = NULL; + user_descr_leaf.user_restore_leaf = NULL; + + scalfmm_build_tree(handle,TreeHeight,boxWidth,boxCenter,user_descr,user_descr_leaf); scalfmm_algorithm_config(handle,periodic); //Creation of an array of particles int nb_of_parts = 2; diff --git a/Addons/CKernelApi/Tests/testUserDefinedKernelApi.c b/Addons/CKernelApi/Tests/testUserDefinedKernelApi.c index 027ef10cba8ae97c05145aaabbdb77b9c7246a5e..0d429f07a0f21ca2c659890a3428442c9842d410 100644 --- a/Addons/CKernelApi/Tests/testUserDefinedKernelApi.c +++ b/Addons/CKernelApi/Tests/testUserDefinedKernelApi.c @@ -282,10 +282,17 @@ int main(int argc, char ** argv){ struct User_Scalfmm_Cell_Descriptor cellDescriptor; cellDescriptor.user_init_cell = my_Callback_init_cell; cellDescriptor.user_free_cell = my_Callback_free_cell; + struct User_Scalfmm_Leaf_Descriptor user_descr_leaf; + user_descr_leaf.user_init_leaf = NULL; + user_descr_leaf.user_free_leaf = NULL; + user_descr_leaf.user_get_size = NULL; + user_descr_leaf.user_copy_leaf = NULL; + user_descr_leaf.user_restore_leaf = NULL; + // Init tree and cell printf("Building the tree and Initizalizing the cells:\n"); - scalfmm_build_tree(handle,treeHeight, boxWidth, boxCenter, cellDescriptor); + scalfmm_build_tree(handle,treeHeight, boxWidth, boxCenter, cellDescriptor, user_descr_leaf); // Insert particles printf("Inserting particles...\n"); scalfmm_tree_insert_particles_xyz(handle, nbParticles, particleXYZ,BOTH); @@ -303,6 +310,7 @@ int main(int argc, char ** argv){ kernel.p2pinner = my_Callback_P2PInner; kernel.p2p = my_Callback_P2P; kernel.p2p_full = NULL; + kernel.p2p_sym = NULL; // Init the data to pass to all our callbacks struct MyData my_data; diff --git a/Addons/FmmApi/CMakeLists.txt b/Addons/FmmApi/CMakeLists.txt deleted file mode 100644 index c462e2484bda9b0aad55d7bcb1d97a3d8531a78d..0000000000000000000000000000000000000000 --- a/Addons/FmmApi/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -# check if compiling into source directories -STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" insource) -if(insource) - MESSAGE(FATAL_ERROR "${PROJECT_NAME} requires an out of source build. Goto ./Build and tapes cmake ../") -endif(insource) - -project(Addons_fmmapi_scalfmm CXX) -ADD_DEFINITIONS( ${ScaLFMM_CXX_FLAGS}) - -# Active language -# ----------------------- -ENABLE_LANGUAGE(CXX ) -MESSAGE(STATUS " CXX ${CMAKE_CXX_COMPILER_ID}" ) - -# Options -OPTION( SCALFMM_ADDON_FMMAPI "Set to ON to build ScaFMM FMM API interface" OFF ) - -# if ask to build addon -if(SCALFMM_ADDON_FMMAPI) - # first build lib scalfmmapi - set(LIBRARY_OUTPUT_PATH ../lib/${CMAKE_BUILD_TYPE}) - - # Searching all cpp file - file( GLOB_RECURSE source_lib_files Src/*.cpp ) - - # Adding cpp files to project - add_library( scalfmmapi STATIC ${source_lib_files} ) - - # Add blas library (even if it is set to off) - target_link_libraries( scalfmmapi scalfmm) - - # Adding the entire project dir as an include dir - INCLUDE_DIRECTORIES( - ${SCALFMM_BINARY_DIR}/Src - ${SCALFMM_SOURCE_DIR}/Src - ${SCALFMM_INCLUDES} - ) - - # Install lib - install( TARGETS scalfmmapi ARCHIVE DESTINATION lib ) - - # Install header - SET(my_include_dirs "Src") - - file( GLOB hpp_in_dir Src/*.hpp ) - INSTALL( FILES ${hpp_in_dir} DESTINATION include/ScalFmm/FmmApi ) - - file( GLOB_RECURSE source_tests_files Tests/*.cpp ) - INCLUDE_DIRECTORIES( ${SCALFMM_BINARY_DIR}/Src ) - - # Then build test files - foreach(exec ${source_tests_files}) - get_filename_component( - execname ${exec} - NAME_WE - ) - - set(compile_exec "TRUE") - - foreach(fuse_key ${FUSE_LIST}) - file(STRINGS "${exec}" lines_fuse REGEX "@FUSE_${fuse_key}") - if(lines_fuse) - if( NOT SCALFMM_USE_${fuse_key} ) - MESSAGE( STATUS "This needs ${fuse_key} = ${exec}" ) - set(compile_exec "FALSE") - endif() - endif() - endforeach() - - # Dependency are OK - if( compile_exec ) - add_executable( ${execname} ${exec} ) - # link to scalfmm and scalfmmapi - target_link_libraries( - ${execname} - ${scalfmm_lib} - scalfmmapi - ${BLAS_LIBRARIES} - ${LAPACK_LIBRARIES} - ${SCALFMM_LIBRARIES} - ) - endif() - endforeach(exec) -endif() - diff --git a/Addons/FmmApi/Src/FmmApi.h b/Addons/FmmApi/Src/FmmApi.h deleted file mode 100644 index 3550ebb6ea823257aadd50ea405bc4586fc3185b..0000000000000000000000000000000000000000 --- a/Addons/FmmApi/Src/FmmApi.h +++ /dev/null @@ -1,114 +0,0 @@ -// =================================================================================== -// Logiciel initial: ScalFmm Version 0.5 -// Co-auteurs : Olivier Coulaud, Bérenger Bramas. -// Propriétaires : INRIA. -// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire. -// Initial software: ScalFmm Version 0.5 -// Co-authors: Olivier Coulaud, Bérenger Bramas. -// Owners: INRIA. -// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license. -// =================================================================================== -#ifndef FMMAPI_H -#define FMMAPI_H - -enum FmmApiErrors { - FMMAPI_NO_ERROR, - FMMAPI_SUPPORTED_PARAMETER, - FMMAPI_UNSUPPORTED_PARAMETER, - FMMAPI_UNKNOWN_PARAMETER -}; - -////////////////////// Opérateurs FMM Core : ////////////////////////// - -enum FmmApiCoreParameters { - FMMCORE_TREE_HEIGHT, // hombre de niveaux de l'arbre (int) - FMMCORE_ROOT_BOX_WIDTH, // taille de la boîte racine (FReal) - FMMCORE_ROOT_BOX_CENTER, // position du centre de la boîte racine (FReal[3]) - FMMCORE_LEAF_BOX_WIDTH, // taille des boîtes feuilles (FReal) - FMMCORE_POINTS_PER_LEAF, // nombre moyen de points par feuille (FReal) - FMMCORE_MPI_COMMUNICATOR, // communicateur MPI (MPI_Comm) - FMMCORE_THREADS_NUMBER, // nombre de threads (int) - FMMCORE_THREAD_ID, // id du thread (int) - FMMCORE_RHS_NUMBER, // nombre de seconds membres (int) - //paramètres en lecture seule : - FMMCORE_HANDLES_P2P // renvoie 0 ou 1 pour dire si le FmmCore gère ou pas le P2P. -}; - -int FmmCore_init(void **fmmCore) ; /*alloue et initialise le FmmCore*/ -int FmmCore_free(void *fmmCore) ; /*libère le FmmCore*/ -int FmmCore_isParameterUsed(void */*fmmCore*/, int *name, int *flag); -int FmmCore_setParameter(void *fmmCore, int *name, void*value); -int FmmCore_setParameter(void *fmmCore, int name, void*value); -int FmmCore_getParameter(void *fmmCore, int *name, void*value); -int FmmCore_getParameter(void *fmmCore, int name, void*value); - - -int FmmCore_getRadius(void*fmmCore, void *boxId, FReal *radius);/*Renvoie le rayon de la boîte*/ -int FmmCore_getCentre(void*/*fmmCore*/, void *boxId, FReal **centre); /*Renvoie dans le FReal[3] centre les coordonnées du centre*/ -int FmmCore_getLevel(void*/*fmmCore*/, void *boxId, int *level); /*Renvoie dans level le niveau de la boîte boxId dans son arbre*/ -int FmmCore_getMultipoleArray(void* /*fmmCore*/, void *boxId, void **F); /*Renvoie dans F l'adresse où stocker l'expansion multipôle associée à la boîte boxId*/ -int FmmCore_getLocalArray(void* /*fmmCore*/, void *boxId, void **F); /*Renvoie dans F l'adresse où stocker l'expansion locale associée à la boîte boxId*/ -int FmmCore_getCoord(void*/*fmmCore*/, void *boxId, int *coord); /*Renvoie dans coord la position dans l'arbre*/ - - -/* Données potentiel/champ */ -int FmmCore_getSource(void* /*fmmCore*/, void *boxId, FReal** position, void** potential, int *number); /* Appelé par P2P et P2M pour obtenir le nombre, la position et le potentiel des sources. -Les différents tableaux sont (éventuellement) alloués par le FmmCore. */ -int FmmCore_releaseSource(void*fmmCore, void *boxId, void* potential, FReal* position); /* si le core veut libérer ces tableaux potentiel et position.*/ -int FmmCore_getTargetPoints(void* /*fmmCore*/, void *boxId, FReal** position, int *number) ; /* : Appelé par P2P et L2P pour obtenir le nombre et la position des points cibles.*/ -int FmmCore_releaseTargetPoints(void*fmmCore, void *boxId, FReal* position); /* si le core veut libérer ce tableau "position".*/ -int FmmCore_getTargetField(void* /*fmmCore*/, void *boxId, FReal* F); /* obtient dans un tableau F alloué/libéré par L2P/P2P les valeurs des champs aux points cible -(pour le cas où P2P et L2P doivent sommer leurs résultats).*/ -int FmmCore_setTargetField(void* /*fmmCore*/, void *boxId, FReal* F); /* transmets au FmmCore dans F les valeurs des champs aux points cibles mis à jour.*/ - -/* Entrée/sortie principale */ -int FmmCore_setKernelData(void *fmmCore, void *fmmKernel); /* stocke l'identifiant du FmmKernel dans le FmmCore. Cela permet par la suite aux -opérateurs FMM d'accéder au FmmKernel, et donc d'accéder aux données spécifiques au kernel -(p.ex. fréquence dans le cas Helmholtz, …)*/ -int FmmCore_getKernelData(void*fmmCore, void **fmmKernel); /* récupère l'identifiant du FmmKernel. */ -int FmmCore_setPositions(void *fmmCore, int *nb, FReal *position) ; /* transmet au FmmCore les potentiels associés aux points sources. -Le tableau potential est alloué et libéré par la routine appelant, le FmmCore doit donc en faire une copie.*/ -int FmmCore_setPotentials(void *fmmCore, void *potentials); /* transmet au FmmCore les potentiels associés aux points sources. -Le tableau potential est alloué et libéré par la routine appelant, le FmmCore doit donc en faire une copie.*/ -int FmmCore_doComputation(void *fmmCore) ; /* réalise le produit multipôle. */ -/* !!! Warning use *filed and not **field */ -int FmmCore_getField(void *fmmCore, void *fields) ;/* récupère après le produit multipôle la valeur des champs en chaque point. -Le tableau field doit être alloué et libéré par la routine appelante. */ - -////////////////////// Opérateurs FMM Kernel : ////////////////////////// - -enum FmmApiKernelParameters { - FMMKERNEL_ACCURACY, // précision demandée à la FMM : 1e-3, 1e-6, ... (FReal) - FMMKERNEL_POTENTIAL_DATA_SIZE, // taille en octet de la donnée "potentiel" pour 1 point source (int) - FMMKERNEL_FIELD_DATA_SIZE, // taille en octet de la donnée "field" pour 1 point cible (int) - //paramètres en lecture seule : - FMMKERNEL_HANDLES_P2P // renvoie 0 ou 1 pour dire si le FmmKernel gère ou pas le P2P. -}; - -/******* Allocation : ******/ -int FmmKernel_init(void *fmmCore, void **fmmKernel);/* : alloue et initialise le FmmKernel */ -int FmmKernel_free(void *fmmKernel); /* libére le FmmKernel */ - -/******* Configuration : ***/ - -int FmmKernel_isParameterUsed(void * /*fmm*/, int *name, int *flag); -int FmmKernel_setParameter(void *fmmKernel, int *name, void*value); -int FmmKernel_setParameter(void *fmmKernel, int name, void*value); -int FmmKernel_getParameter(void *fmmKernel, int *name, void*value); -int FmmKernel_getParameter(void *fmmKernel, int name, void*value); - -/****** Données FMM : *****/ -int FmmKernel_getMultipoleArraySize(void *fmmCore, int *size); /* Renvoie dans size la taille (en octets) de l'expansion multipôle associée à la boîte boxId */ -int FmmKernel_getLocalArraySize(void *fmmCore, int *size); /* Renvoie dans size la taille (en octets) de l'expansion locale associée à la boîte boxId*/ - -/******* Opérateurs FMM : **/ -int FmmKernel_P2M(void *fmmCore, void* boxId); -int FmmKernel_L2P(void *fmmCore, void* boxId); -int FmmKernel_M2M(void *fmmCore, void *boxIdFather, void *boxIdSon); -int FmmKernel_L2L(void *fmmCore, void *boxIdFather, void *boxIdSon); -int FmmKernel_M2L(void *fmmCore, void *boxIdSrc, void *boxIdDest); -int FmmKernel_P2P_inner(void *fmmCore, void *boxIdSrcDest); -int FmmKernel_P2P(void *fmmCore, void *boxIdSrc, void *boxIdDest); /* pas mutuel, i.e. on fait seulement dans 1 sens. */ - - -#endif // FMMAPI_H diff --git a/Addons/FmmApi/Src/ScalfmmApiCore.cpp b/Addons/FmmApi/Src/ScalfmmApiCore.cpp deleted file mode 100644 index bd0a87cc7b5cbc13ed31148fc5108cff04a88165..0000000000000000000000000000000000000000 --- a/Addons/FmmApi/Src/ScalfmmApiCore.cpp +++ /dev/null @@ -1,662 +0,0 @@ -// =================================================================================== -// Logiciel initial: ScalFmm Version 0.5 -// Co-auteurs : Olivier Coulaud, Bérenger Bramas. -// Propriétaires : INRIA. -// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire. -// Initial software: ScalFmm Version 0.5 -// Co-authors: Olivier Coulaud, Bérenger Bramas. -// Owners: INRIA. -// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license. -// =================================================================================== -#include "../../Src/Containers/FOctree.hpp" -#include "../../Src/Containers/FVector.hpp" - -#include "../../Src/Components/FSimpleLeaf.hpp" -#include "../../Src/Components/FBasicCell.hpp" - -#include "../../Src/Utils/FPoint.hpp" - -#include "../../Src/Core/FFmmAlgorithm.hpp" -#include "../../Src/Core/FFmmAlgorithmThread.hpp" -#include "../../Src/Core/FFmmAlgorithmTask.hpp" - -#include "../../Src/Components/FBasicKernels.hpp" - -#include "../../Src/Components/FBasicParticleContainer.hpp" - -#ifdef SCALFMM_USE_MPI -#include "../../Src/Utils/FMpi.hpp" -#endif - -#include "FmmApi.h" - -template -class CoreCell : public FBasicCell { - char* multipole; - char* local; - int level; - FReal positions[3]; - mutable ContainerClass* container; - -public: - CoreCell() : multipole(nullptr), local(nullptr), level(0), container(nullptr) { - } - void createArrays(const int multipoleSize, const int localSize){ - multipole = new char[multipoleSize]; - local = new char[localSize]; - - memset(multipole, 0, multipoleSize); - memset(local, 0, localSize); - } - ~CoreCell(){ - delete[] multipole; - delete[] local; - } - - const void* getMultipole() const{ - return multipole; - } - - const void* getLocal() const{ - return local; - } - - void* getMultipole(){ - return multipole; - } - - void* getLocal(){ - return local; - } - - void setLevel(const int inLevel){ - level = inLevel; - } - - int getLevel() const { - return level; - } - - void setPosition(const FReal inPositions[3]){ - positions[0] = inPositions[0]; - positions[1] = inPositions[1]; - positions[2] = inPositions[2]; - } - - const FReal* getPosition() const { - return positions; - } - - void setContainer(ContainerClass* inContainer) const { - container = inContainer; - } - - ContainerClass* getContainer() const { - return container; - } -}; - - - -template< class CellClass, class ContainerClass> -class CoreKernel : public FAbstractKernels { - void* fmmCore; - -public: - CoreKernel(void* inFmmCore): fmmCore(inFmmCore){ - } - - /** Default destructor */ - virtual ~CoreKernel(){ - } - - /** Do nothing */ - virtual void P2M(CellClass* const cell, const ContainerClass* const container) { - cell->setContainer(const_cast(container)); - FmmKernel_P2M(fmmCore,(void*) cell); - } - - /** Do nothing */ - virtual void M2M(CellClass* const FRestrict cell, const CellClass*const FRestrict *const FRestrict children, const int ) { - for(int idx = 0 ; idx < 8 ; ++idx){ - if( children[idx] ){ - FmmKernel_M2M(fmmCore, (void*)cell, (void*)children[idx]); - } - } - } - - /** Do nothing */ - virtual void M2L(CellClass* const FRestrict cell, const CellClass* interactions[], const int , const int ) { - for(int idx = 0 ; idx < 343 ; ++idx){ - if( interactions[idx] ){ - FmmKernel_M2L(fmmCore, (void*)cell, (void*)interactions[idx]); - } - } - } - - /** Do nothing */ - virtual void L2L(const CellClass* const FRestrict cell, CellClass* FRestrict *const FRestrict children, const int ) { - for(int idx = 0 ; idx < 8 ; ++idx){ - if( children[idx] ){ - FmmKernel_L2L(fmmCore, (void*)cell, (void*)children[idx]); - } - } - } - - /** Do nothing */ - virtual void L2P(const CellClass* const cell, ContainerClass* const container){ - cell->setContainer((ContainerClass*)container); - FmmKernel_L2P(fmmCore, (void*)cell); - } - - - /** Do nothing */ - virtual void P2P(const FTreeCoordinate& , - ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict /*sources*/, - ContainerClass* const neighbors[27], const int ){ - CellClass* cell = (CellClass*)targets->getParentCell(); - FmmKernel_P2P_inner(fmmCore, cell); - - for(int idx = 0 ; idx < 27 ; ++idx){ - if( neighbors[idx] ){ - FmmKernel_P2P(fmmCore, (CellClass*)neighbors[idx]->getParentCell(), cell); - } - } - } - - /** Do nothing */ - virtual void P2PRemote(const FTreeCoordinate& , - ContainerClass* const FRestrict , const ContainerClass* const FRestrict , - ContainerClass* const [27], const int ){ - printf("Error remote not implemented!!!!\n"); - } - -}; - - -class CoreVector { - mutable void* parentCell; - void* fields; - int sizeOfField; - void* potentials; - int sizeOfPential; - FVector positions; - FVector indexes; -public: - CoreVector() : parentCell(nullptr), fields(nullptr), sizeOfField(0), - potentials(nullptr), sizeOfPential(0){ - } - - ~CoreVector(){ - delete[] (char*)fields; - delete[] (char*)potentials; - } - - void setParentCell(void* inCell) const{ - parentCell = inCell; - } - - void* getParentCell() const{ - return parentCell; - } - - void allocateFields(const int memSizePerParticles){ - if(fields) delete[](char*)fields; - fields = new char[getNbParticles() * memSizePerParticles]; - sizeOfField = memSizePerParticles; - memset(fields, 0, getNbParticles() * memSizePerParticles); - } - - void* getFields() const{ - return fields; - } - - int getSizeOfField() const{ - return sizeOfField; - } - - void allocatePotentials(const int memSizePerParticles){ - if(potentials) delete[](char*)potentials; - potentials = new char[getNbParticles() * memSizePerParticles]; - sizeOfPential = memSizePerParticles; - memset(potentials, 0, getNbParticles() * memSizePerParticles); - } - - void* getPotentials() const{ - return potentials; - } - - int getSizeOfPotential() const{ - return sizeOfPential; - } - - const int* getIndexes() const { - return indexes.data(); - } - - const FReal* getPositions() const { - return positions.data(); - } - - int getNbParticles() { - return indexes.getSize(); - } - - void push(const FPoint& partPosition, const int partIndex){ - positions.push(partPosition.getX()); - positions.push(partPosition.getY()); - positions.push(partPosition.getZ()); - indexes.push(partIndex); - } -}; - - -typedef CoreVector CoreContainerClass; - -typedef CoreCell CoreCellClass; -typedef FSimpleLeaf LeafClass; -typedef FOctree OctreeClass; -typedef CoreKernel CoreKernelClass; - -typedef FFmmAlgorithm FmmClass; -typedef FFmmAlgorithmThread FmmClassThread; - - -struct ScalFmmCoreHandle { - struct ScalFmmCoreConfig { - //paramètres en lecture/écriture : - int treeHeight; // hombre de niveaux de l'arbre (int) - FReal boxWidth; // taille de la boîte racine (FReal) - FReal boxCenter[3]; // position du centre de la boîte racine (FReal[3]) -#ifdef SCALFMM_USE_MPI - MPI_Comm mpiCom; // communicateur MPI (MPI_Comm) -#endif - int nbThreads; // nombre de threads (int) - int rhsNumber; // nombre de seconds membres (int) - }; - - ScalFmmCoreConfig config; - OctreeClass* octree; - void *kernelHandle; -}; - -int FmmCore_init(void **fmmCore) { - ScalFmmCoreHandle* corehandle = new ScalFmmCoreHandle; - memset(corehandle, 0, sizeof(corehandle)); - - corehandle->config.nbThreads = omp_get_max_threads(); - - *fmmCore = corehandle; - - return FMMAPI_NO_ERROR; -} /*alloue et initialise le FmmCore*/ - - -int FmmCore_free(void *fmmCore) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - if(corehandle->octree) delete corehandle->octree; - delete corehandle; - return FMMAPI_NO_ERROR; -} /*libère le FmmCore*/ - -int FmmCore_isParameterUsed(void */*fmmCore*/, int *name, int *flag){ - switch( *name ){ - case FMMCORE_ROOT_BOX_WIDTH : - case FMMCORE_ROOT_BOX_CENTER : - case FMMCORE_TREE_HEIGHT : -#ifdef SCALFMM_USE_MPI - case FMMCORE_MPI_COMMUNICATOR: -#endif - case FMMCORE_THREADS_NUMBER: - case FMMCORE_THREAD_ID: - case FMMCORE_RHS_NUMBER: - case FMMCORE_HANDLES_P2P: - *flag = FMMAPI_SUPPORTED_PARAMETER; - break; - case FMMCORE_LEAF_BOX_WIDTH : - case FMMCORE_POINTS_PER_LEAF : - *flag = FMMAPI_UNSUPPORTED_PARAMETER; - break; - default: - *flag = FMMAPI_UNKNOWN_PARAMETER; - } - - return FMMAPI_NO_ERROR; -} - -int FmmCore_setParameter(void *fmmCore, int *name, void*value){ - int flag; - - FmmCore_isParameterUsed(fmmCore, name, &flag); - if( flag != FMMAPI_SUPPORTED_PARAMETER){ - return flag; - } - - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - switch( *name ){ - case FMMCORE_TREE_HEIGHT : - corehandle->config.treeHeight = *(int*)value ; - break; - case FMMCORE_ROOT_BOX_WIDTH : - corehandle->config.boxWidth = *(FReal*)value; - break; - case FMMCORE_ROOT_BOX_CENTER : - memcpy(corehandle->config.boxCenter, value, sizeof(FReal)*3); - break; -#ifdef SCALFMM_USE_MPI - case FMMCORE_MPI_COMMUNICATOR: - corehandle->config.mpiCom = *(MPI_Comm*)value; - break; -#endif - case FMMCORE_THREADS_NUMBER: - corehandle->config.nbThreads = *(int*)value; - break; - case FMMCORE_RHS_NUMBER: - corehandle->config.rhsNumber = *(int*)value; - break; - case FMMCORE_HANDLES_P2P: - case FMMCORE_THREAD_ID: - return FMMAPI_UNSUPPORTED_PARAMETER; - default: - return FMMAPI_UNKNOWN_PARAMETER; - } - - return FMMAPI_NO_ERROR; -} - -int FmmCore_setParameter(void *fmmCore, int name, void*value){ - return FmmCore_setParameter(fmmCore, &name, value); -} - - -int FmmCore_getParameter(void *fmmCore, int *name, void*value){ - int flag; - - FmmCore_isParameterUsed(fmmCore, name, &flag); - if( flag != FMMAPI_SUPPORTED_PARAMETER){ - return flag; - } - - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - switch( *name ){ - case FMMCORE_TREE_HEIGHT : - *(int*)value = corehandle->config.treeHeight; - break; - case FMMCORE_ROOT_BOX_WIDTH : - *(FReal*)value = corehandle->config.boxWidth; - break; - case FMMCORE_ROOT_BOX_CENTER : - memcpy(value,corehandle->config.boxCenter, sizeof(FReal)*3); - break; -#ifdef SCALFMM_USE_MPI - case FMMCORE_MPI_COMMUNICATOR: - *(MPI_Comm*)value = corehandle->config.mpiCom; - break; -#endif - case FMMCORE_THREADS_NUMBER: - *(int*)value = corehandle->config.nbThreads; - break; - case FMMCORE_THREAD_ID: - *(int*)value = omp_get_thread_num(); - break; - case FMMCORE_RHS_NUMBER: - *(int*)value = corehandle->config.rhsNumber; - break; - case FMMCORE_HANDLES_P2P: - *(int*)value = true; - break; - default: - return FMMAPI_UNKNOWN_PARAMETER; - } - - return FMMAPI_NO_ERROR; -} - -int FmmCore_getParameter(void *fmmCore, int name, void*value){ - return FmmCore_getParameter(fmmCore, &name, value); -} - - -int FmmCore_getRadius(void*fmmCore, void *boxId, FReal *radius) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - *radius = corehandle->octree->getBoxWidth() / FReal(1<getLevel()); - return FMMAPI_NO_ERROR; -} /*Renvoie le rayon de la boîte*/ - -int FmmCore_getCentre(void*/*fmmCore*/, void *boxId, FReal **centre) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - - (*centre)[0] = boxhandle->getPosition()[0]; - (*centre)[1] = boxhandle->getPosition()[1]; - (*centre)[2] = boxhandle->getPosition()[2]; - - return FMMAPI_NO_ERROR; -} /*Renvoie dans le FReal[3] centre les coordonnées du centre*/ - -int FmmCore_getLevel(void*/*fmmCore*/, void *boxId, int *level) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - *level = boxhandle->getLevel(); - return FMMAPI_NO_ERROR; -} /*Renvoie dans level le niveau de la boîte boxId dans son arbre*/ - -int FmmCore_getMultipoleArray(void* /*fmmCore*/, void *boxId, void **F) { - CoreCellClass* cell = (CoreCellClass*)boxId; - *F = cell->getMultipole(); - return FMMAPI_NO_ERROR; -} /*Renvoie dans F l'adresse où stocker l'expansion multipôle associée à la boîte boxId*/ - -int FmmCore_getLocalArray(void* /*fmmCore*/, void *boxId, void **F) { - CoreCellClass* cell = (CoreCellClass*)boxId; - *F = cell->getLocal(); - return FMMAPI_NO_ERROR; -} /*Renvoie dans F l'adresse où stocker l'expansion locale associée à la boîte boxId*/ - -int FmmCore_getCoord(void*/*fmmCore*/, void *boxId, int *coord) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - coord[0] = boxhandle->getCoordinate().getX(); - coord[1] = boxhandle->getCoordinate().getY(); - coord[2] = boxhandle->getCoordinate().getZ(); - return FMMAPI_NO_ERROR; -} /*Renvoie dans coord la position dans l'arbre*/ - - -/* Données potentiel/champ */ -int FmmCore_getSource(void* /*fmmCore*/, void *boxId, FReal** position, void** potential, int *number) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - CoreContainerClass* sources = boxhandle->getContainer(); - - *number = sources->getNbParticles(); - *position = const_cast(sources->getPositions()); - *potential = sources->getPotentials(); - - return FMMAPI_NO_ERROR; -} /* Appelé par P2P et P2M pour obtenir le nombre, la position et le potentiel des sources. -Les différents tableaux sont (éventuellement) alloués par le FmmCore. */ - -int FmmCore_releaseSource(void*fmmCore, void *boxId, void* potential, FReal* position) { - return FMMAPI_NO_ERROR; -} /* si le core veut libérer ces tableaux potentiel et position.*/ - -int FmmCore_getTargetPoints(void* /*fmmCore*/, void *boxId, FReal** position, int *number) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - CoreContainerClass* targets = boxhandle->getContainer(); - - *number = targets->getNbParticles(); - *position = const_cast(targets->getPositions()); - - return FMMAPI_NO_ERROR; -} /* : Appelé par P2P et L2P pour obtenir le nombre et la position des points cibles.*/ - -int FmmCore_releaseTargetPoints(void*fmmCore, void *boxId, FReal* position) { - return FMMAPI_NO_ERROR; -} /* si le core veut libérer ce tableau "position".*/ - -int FmmCore_getTargetField(void* /*fmmCore*/, void *boxId, FReal* F) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - CoreContainerClass* targets = boxhandle->getContainer(); - - memcpy(F, targets->getFields(), targets->getNbParticles() * targets->getSizeOfField()); - - return FMMAPI_NO_ERROR; -} /* obtient dans un tableau F alloué/libéré par L2P/P2P les valeurs des champs aux points cible -(pour le cas où P2P et L2P doivent sommer leurs résultats).*/ - -int FmmCore_setTargetField(void* /*fmmCore*/, void *boxId, FReal* F) { - CoreCellClass* boxhandle = (CoreCellClass*)boxId; - CoreContainerClass* targets = boxhandle->getContainer(); - - memcpy(targets->getFields(), F, targets->getNbParticles() * targets->getSizeOfField()); - - return FMMAPI_NO_ERROR; -} /* transmets au FmmCore dans F les valeurs des champs aux points cibles mis à jour.*/ - - - -/* Entrée/sortie principale */ -int FmmCore_setKernelData(void *fmmCore, void *fmmKernel) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - corehandle->kernelHandle = fmmKernel; - return FMMAPI_NO_ERROR; -} /* stocke l'identifiant du FmmKernel dans le FmmCore. Cela permet par la suite aux -opérateurs FMM d'accéder au FmmKernel, et donc d'accéder aux données spécifiques au kernel -(p.ex. fréquence dans le cas Helmholtz, …)*/ - -int FmmCore_getKernelData(void*fmmCore, void **fmmKernel) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - *fmmKernel = corehandle->kernelHandle; - return FMMAPI_NO_ERROR; -} /* récupère l'identifiant du FmmKernel. */ - - -int FmmCore_setPositions(void *fmmCore, int *nb, FReal *position) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - - corehandle->octree = new OctreeClass(corehandle->config.treeHeight, FMath::Min(3,corehandle->config.treeHeight-1), - corehandle->config.boxWidth, FPoint(corehandle->config.boxCenter)); - - if( corehandle->config.nbThreads != 0){ - omp_set_num_threads(corehandle->config.nbThreads); - } - - for(FSize idxPart = 0 ; idxPart < (*nb) ; ++idxPart){ - const FReal* pos = &position[idxPart * 3]; - corehandle->octree->insert(FPoint(pos[0], pos[1], pos[2]),idxPart); - } - - return FMMAPI_NO_ERROR; -} /* transmet au FmmCore les potentiels associés aux points sources. -Le tableau potential est alloué et libéré par la routine appelant, le FmmCore doit donc en faire une copie.*/ - - -int FmmCore_setPotentials(void *fmmCore, void *potentials) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - OctreeClass* octree = corehandle->octree; - - void* fmmKernel; - FmmCore_getKernelData(fmmCore, &fmmKernel); - - int sizeOfPotentials; - FmmKernel_getParameter(fmmKernel, FMMKERNEL_POTENTIAL_DATA_SIZE, &sizeOfPotentials); - - typename OctreeClass::Iterator octreeIterator(octree); - octreeIterator.gotoBottomLeft(); - do{ - CoreContainerClass* particles = octreeIterator.getCurrentLeaf()->getSrc(); - particles->allocatePotentials(sizeOfPotentials); - - for(int idx = 0 ; idx < particles->getNbParticles() ; ++idx){ - memcpy(((char*)particles->getPotentials())+idx*sizeOfPotentials, - ((char*)potentials)+particles->getIndexes()[idx]*sizeOfPotentials, - sizeOfPotentials); - } - - } while( octreeIterator.moveRight() ); - - return FMMAPI_NO_ERROR; -} /* transmet au FmmCore les potentiels associés aux points sources. -Le tableau potential est alloué et libéré par la routine appelant, le FmmCore doit donc en faire une copie.*/ - -int FmmCore_doComputation(void *fmmCore) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - - { // Ceck if there is number of NbPart summed at level 1 - FPoint corner = corehandle->octree->getBoxCenter(); - corner -= (corehandle->octree->getBoxWidth()/2); - - FReal boxWidth = corehandle->octree->getBoxWidth()/( 1<< (corehandle->config.treeHeight-1) ); - - typename OctreeClass::Iterator octreeIterator(corehandle->octree); - octreeIterator.gotoBottomLeft(); - for(int idxLevel = corehandle->config.treeHeight - 1 ; idxLevel >= 1 ; --idxLevel ){ - int multipoleSize; - int localSize; - - FmmKernel_getMultipoleArraySize(fmmCore, &multipoleSize); - FmmKernel_getLocalArraySize(fmmCore, &localSize); - - do{ - octreeIterator.getCurrentCell()->createArrays(multipoleSize, localSize); - octreeIterator.getCurrentCell()->setLevel(idxLevel); - const FTreeCoordinate coord = octreeIterator.getCurrentCell()->getCoordinate(); - FPoint position( coord.getX()*boxWidth + boxWidth/2.0 + corner.getX(), - coord.getY()*boxWidth + boxWidth/2.0 + corner.getY(), - coord.getZ()*boxWidth + boxWidth/2.0 + corner.getZ()); - octreeIterator.getCurrentCell()->setPosition(position.getDataValue()); - } while( octreeIterator.moveRight() ); - - octreeIterator.moveUp(); - octreeIterator.gotoLeft(); - - boxWidth *= FReal(2.0); - } - } - { // Ceck if there is number of NbPart summed at level 1 - void* fmmKernel; - FmmCore_getKernelData(fmmCore, &fmmKernel); - - int sizeOfFields; - FmmKernel_getParameter(fmmKernel, FMMKERNEL_FIELD_DATA_SIZE, &sizeOfFields); - - typename OctreeClass::Iterator octreeIterator(corehandle->octree); - octreeIterator.gotoBottomLeft(); - do{ - octreeIterator.getCurrentLeaf()->getTargets()->setParentCell(octreeIterator.getCurrentCell()); - octreeIterator.getCurrentLeaf()->getTargets()->allocateFields(sizeOfFields); - } while( octreeIterator.moveRight() ); - } - - if( corehandle->config.nbThreads <= 1){ - CoreKernelClass kernels(fmmCore ); - FmmClass algo(corehandle->octree,&kernels); - algo.execute(); - } - else{ - CoreKernelClass kernels(fmmCore ); - FmmClassThread algo(corehandle->octree,&kernels); - algo.execute(); - } - - return FMMAPI_NO_ERROR; -} /* réalise le produit multipôle. */ - -/* !!! Warning use *filed and not **field */ -int FmmCore_getField(void *fmmCore, void *fields) { - ScalFmmCoreHandle* corehandle = (ScalFmmCoreHandle*)fmmCore; - - typename OctreeClass::Iterator octreeIterator(corehandle->octree); - octreeIterator.gotoBottomLeft(); - do{ - CoreContainerClass* particles = octreeIterator.getCurrentLeaf()->getTargets(); - for(int idx = 0 ; idx < particles->getNbParticles() ; ++idx){ - memcpy(((char*)fields)+particles->getIndexes()[idx]*particles->getSizeOfField(), - ((char*)particles->getFields())+idx*particles->getSizeOfField(), - particles->getSizeOfField()); - } - } while(octreeIterator.moveRight()); - - return FMMAPI_NO_ERROR; -} /* récupère après le produit multipôle la valeur des champs en chaque point. -Le tableau field doit être alloué et libéré par la routine appelante. */ - - diff --git a/Addons/FmmApi/Src/ScalfmmApiRotation.cpp b/Addons/FmmApi/Src/ScalfmmApiRotation.cpp deleted file mode 100644 index b6a55a85a2490575cc5d158e752d35f24cb3d6c0..0000000000000000000000000000000000000000 --- a/Addons/FmmApi/Src/ScalfmmApiRotation.cpp +++ /dev/null @@ -1,508 +0,0 @@ -// =================================================================================== -// Logiciel initial: ScalFmm Version 0.5 -// Co-auteurs : Olivier Coulaud, Bérenger Bramas. -// Propriétaires : INRIA. -// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire. -// Initial software: ScalFmm Version 0.5 -// Co-authors: Olivier Coulaud, Bérenger Bramas. -// Owners: INRIA. -// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license. -// =================================================================================== -#include "../../Src/Utils/FGlobal.hpp" -#include "../../Src/Utils/FAssert.hpp" - -#include "../../Src/Containers/FVector.hpp" - -#include "../../Src/Components/FSimpleLeaf.hpp" - -#include "../../Src/Utils/FPoint.hpp" - -#include "../../Src/Kernels/Rotation/FRotationCell.hpp" -#include "../../Src/Kernels/Rotation/FRotationKernel.hpp" -#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp" - -#include "FmmApi.h" - -////////////////////// Opérateurs FMM Kernel : ////////////////////////// - -class KernelCell : public FBasicCell { - FComplex* multipole; - FComplex* local; -public: - KernelCell() : multipole(nullptr), local(nullptr){ - } - void attachArrays(FComplex inMultipole[], FComplex inLocal[]){ - multipole = inMultipole; - local = inLocal; - } - - const FComplex* getMultipole() const{ - return multipole; - } - - const FComplex* getLocal() const{ - return local; - } - - FComplex* getMultipole(){ - return multipole; - } - - FComplex* getLocal(){ - return local; - } -}; - - -static const int P = 5; - -typedef KernelCell KernelCellClass; -typedef FP2PParticleContainer ContainerClass; -typedef FSimpleLeaf LeafClass; -typedef FRotationKernel< KernelCellClass, ContainerClass , P> KernelClass; - -struct ScalFmmKernelHandle { - KernelClass** kernel; - int potentialDataSize; - int fieldDataSize; - int nbthread; -}; - -/******* Allocation : ******/ -int FmmKernel_init(void *fmmCore, void **fmmKernel){ - ScalFmmKernelHandle* kernelhandle = new ScalFmmKernelHandle; - memset(kernelhandle, 0, sizeof(ScalFmmKernelHandle)); - - int NbLevels; - FmmCore_getParameter(fmmCore, FMMCORE_TREE_HEIGHT, &NbLevels); - FReal boxWidth; - FmmCore_getParameter(fmmCore, FMMCORE_ROOT_BOX_WIDTH, &boxWidth); - FReal centerOfBox[3]; - FmmCore_getParameter(fmmCore, FMMCORE_ROOT_BOX_CENTER, centerOfBox); - - FmmCore_getParameter(fmmCore, FMMCORE_THREADS_NUMBER, &kernelhandle->nbthread); - - KernelClass original( NbLevels, boxWidth, FPoint(centerOfBox) ); - kernelhandle->kernel = new KernelClass*[kernelhandle->nbthread]; - for(int idxThread = 0 ; idxThread < kernelhandle->nbthread ; ++idxThread){ - kernelhandle->kernel[idxThread] = new KernelClass(original); - } - - kernelhandle->potentialDataSize = 1; - kernelhandle->fieldDataSize = 4; - - *fmmKernel = kernelhandle; - - return FMMAPI_NO_ERROR; -}/* : alloue et initialise le FmmKernel */ -int FmmKernel_free(void *fmmKernel){ - ScalFmmKernelHandle* kernelhandle = (ScalFmmKernelHandle*) fmmKernel; - - for(int idxThread = 0 ; idxThread < kernelhandle->nbthread ; ++idxThread){ - delete kernelhandle->kernel[idxThread]; - } - - delete[] kernelhandle->kernel; - delete kernelhandle; - - return FMMAPI_NO_ERROR; -} /* libére le FmmKernel */ - - - - -/******* Configuration : ***/ - -int FmmKernel_isParameterUsed(void * /*fmm*/, int *name, int *flag){ - switch( *name ){ - case FMMKERNEL_POTENTIAL_DATA_SIZE: - case FMMKERNEL_FIELD_DATA_SIZE: - case FMMKERNEL_HANDLES_P2P: - *flag = FMMAPI_SUPPORTED_PARAMETER; - break; - case FMMKERNEL_ACCURACY : - *flag = FMMAPI_UNSUPPORTED_PARAMETER; - break; - default: - *flag = FMMAPI_UNKNOWN_PARAMETER; - } - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_setParameter(void *fmmKernel, int *name, void*value){ - /*ScalFmmKernelHandle* kernelhandle = (ScalFmmKernelHandle*) fmmKernel;*/ - int flag; - - FmmKernel_isParameterUsed(fmmKernel, name, &flag); - if( flag != FMMAPI_SUPPORTED_PARAMETER){ - return flag; - } - - switch( *name ){ - case FMMKERNEL_POTENTIAL_DATA_SIZE : - case FMMKERNEL_FIELD_DATA_SIZE : - return FMMAPI_SUPPORTED_PARAMETER; - default: - return FMMAPI_UNKNOWN_PARAMETER; - } - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_setParameter(void *fmmKernel, int name, void*value){ - return FmmKernel_setParameter( fmmKernel, &name, value); -} - -int FmmKernel_getParameter(void *fmmKernel, int *name, void*value){ - ScalFmmKernelHandle* kernelhandle = (ScalFmmKernelHandle*) fmmKernel; - int flag; - - FmmKernel_isParameterUsed(fmmKernel, name, &flag); - if( flag != FMMAPI_SUPPORTED_PARAMETER){ - return flag; - } - - switch( *name ){ - case FMMKERNEL_POTENTIAL_DATA_SIZE : - *(int*)value = kernelhandle->potentialDataSize*sizeof(FReal); - break; - case FMMKERNEL_FIELD_DATA_SIZE : - *(int*)value = kernelhandle->fieldDataSize*sizeof(FReal); - break; - default: - return FMMAPI_UNKNOWN_PARAMETER; - } - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_getParameter(void *fmmKernel, int name, void*value){ - return FmmKernel_getParameter(fmmKernel, &name, value); -} - - -/****** Données FMM : *****/ -int FmmKernel_getMultipoleArraySize(void */*fmmCore*/, int *size) { - *size = ((P+2)*(P+1))/2 * sizeof(FComplex); - return FMMAPI_NO_ERROR; -} /* Renvoie dans size la taille (en octets) de l'expansion multipôle associée à la boîte boxId */ - -int FmmKernel_getLocalArraySize(void */*fmmCore*/, int *size){ - *size = ((P+2)*(P+1))/2 * sizeof(FComplex); - return FMMAPI_NO_ERROR; -} /* Renvoie dans size la taille (en octets) de l'expansion locale associée à la boîte boxId*/ - - -/******* Opérateurs FMM : **/ -int FmmKernel_P2M(void *fmmCore, void* boxId){ - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FComplex* multipole; - FmmCore_getMultipoleArray(fmmCore, boxId, (void**)&multipole); - - KernelCellClass cell; - cell.attachArrays(multipole, nullptr); - int coord[3]; - FmmCore_getCoord(fmmCore, boxId, coord); - cell.setCoordinate(coord[0], coord[1], coord[2]); - - FReal* positions; - FReal* physicalValues; - int number; - FmmCore_getSource(fmmCore, boxId, &positions, (void**)&physicalValues, &number); - - FP2PParticleContainer sources; - for(FSize idxPart = 0 ; idxPart < number ; ++idxPart){ - sources.push(FPoint(positions[idxPart*3],positions[idxPart*3+1],positions[idxPart*3+2]),physicalValues[idxPart]); - } - - kernelhandle->kernel[threadId]->P2M(&cell, &sources); - - FmmCore_releaseSource(fmmCore, boxId, physicalValues, positions); - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_L2P(void *fmmCore, void* boxId){ - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FComplex* local; - FmmCore_getLocalArray(fmmCore, boxId, (void**)&local); - - KernelCellClass cell; - cell.attachArrays(nullptr,local); - int coord[3]; - FmmCore_getCoord(fmmCore, boxId, coord); - cell.setCoordinate(coord[0], coord[1], coord[2]); - - FReal* physicalValues; - FReal* positions; - int number; - FmmCore_getSource(fmmCore, boxId, &positions, (void**)&physicalValues, &number); - - FReal* fields = new FReal[number*kernelhandle->fieldDataSize]; - FmmCore_getTargetField(fmmCore, boxId, fields); - - FP2PParticleContainer targets; - for(FSize idxPart = 0 ; idxPart < number ; ++idxPart){ - targets.push(FPoint(&positions[idxPart*3]),physicalValues[idxPart], - fields[idxPart*kernelhandle->fieldDataSize], - fields[idxPart*kernelhandle->fieldDataSize+1], - fields[idxPart*kernelhandle->fieldDataSize+2], - fields[idxPart*kernelhandle->fieldDataSize+3]); - } - - kernelhandle->kernel[threadId]->L2P(&cell, &targets); - - const FReal*const potentials = targets.getPotentials(); - const FReal*const forcesX = targets.getForcesX(); - const FReal*const forcesY = targets.getForcesY(); - const FReal*const forcesZ = targets.getForcesZ(); - - for(FSize idxPart = 0 ; idxPart < number ; ++idxPart){ - fields[idxPart*kernelhandle->fieldDataSize] += potentials[idxPart]; - fields[idxPart*kernelhandle->fieldDataSize+1] += forcesX[idxPart]; - fields[idxPart*kernelhandle->fieldDataSize+2] += forcesY[idxPart]; - fields[idxPart*kernelhandle->fieldDataSize+3] += forcesZ[idxPart]; - } - - FmmCore_releaseTargetPoints(fmmCore, boxId, positions); - FmmCore_setTargetField(fmmCore, boxId, fields); - delete[] fields; - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_M2M(void *fmmCore, void *boxIdFather, void *boxIdSon){ - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FComplex* multipole; - FmmCore_getMultipoleArray(fmmCore, boxIdFather, (void**)&multipole); - - KernelCellClass cellFather; - cellFather.attachArrays(multipole, nullptr); - int coordFather[3]; - FmmCore_getCoord(fmmCore, boxIdFather, coordFather); - cellFather.setCoordinate(coordFather[0], coordFather[1], coordFather[2]); - - FmmCore_getMultipoleArray(fmmCore, boxIdSon, (void**)&multipole); - - KernelCellClass cellSon; - cellSon.attachArrays(multipole, nullptr); - int coordChild[3]; - FmmCore_getCoord(fmmCore, boxIdSon, coordChild); - cellSon.setCoordinate(coordChild[0], coordChild[1], coordChild[2]); - - int level; - FmmCore_getLevel(fmmCore,boxIdFather, &level); - - const KernelCellClass* children[8]; - memset(children, 0, sizeof(KernelCellClass*)*8); - const int mindex = ((coordChild[0]&1) * 2 + (coordChild[1]&1)) * 2 + (coordChild[2]&1); - children[mindex] = &cellSon; - - kernelhandle->kernel[threadId]->M2M(&cellFather, children, level); - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_L2L(void *fmmCore, void *boxIdFather, void *boxIdSon){ - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FComplex* local; - FmmCore_getLocalArray(fmmCore, boxIdFather, (void**)&local); - - KernelCellClass cellFather; - cellFather.attachArrays(nullptr, local); - int coordFather[3]; - FmmCore_getCoord(fmmCore, boxIdFather, coordFather); - cellFather.setCoordinate(coordFather[0], coordFather[1], coordFather[2]); - - FmmCore_getLocalArray(fmmCore, boxIdSon, (void**)&local); - - KernelCellClass cellSon; - cellSon.attachArrays(nullptr, local); - int coordChild[3]; - FmmCore_getCoord(fmmCore, boxIdSon, coordChild); - cellSon.setCoordinate(coordChild[0], coordChild[1], coordChild[2]); - - int level; - FmmCore_getLevel(fmmCore,boxIdFather, &level); - - KernelCellClass* children[8]; - memset(children, 0, sizeof(KernelCellClass*)*8); - const int mindex = ((coordChild[0]&1) * 2 + (coordChild[1]&1)) * 2 + (coordChild[2]&1); - children[mindex] = &cellSon; - - kernelhandle->kernel[threadId]->L2L(&cellFather, children, level); - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_M2L(void *fmmCore, void *boxIdSrc, void *boxIdDest){ - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FComplex* multipole; - FmmCore_getMultipoleArray(fmmCore, boxIdSrc, (void**)&multipole); - KernelCellClass cellSrc; - cellSrc.attachArrays(multipole,nullptr); - int coord[3]; - FmmCore_getCoord(fmmCore, boxIdSrc, coord); - cellSrc.setCoordinate(coord[0], coord[1], coord[2]); - - FComplex* local; - FmmCore_getLocalArray(fmmCore, boxIdDest, (void**)&local); - KernelCellClass cellDst; - cellDst.attachArrays(nullptr, local); - FmmCore_getCoord(fmmCore, boxIdDest, coord); - cellDst.setCoordinate(coord[0], coord[1], coord[2]); - - int level; - FmmCore_getLevel(fmmCore, boxIdDest, &level); - - const int xdiff = cellSrc.getCoordinate().getX() - cellDst.getCoordinate().getX(); - const int ydiff = cellSrc.getCoordinate().getY() - cellDst.getCoordinate().getY(); - const int zdiff = cellSrc.getCoordinate().getZ() - cellDst.getCoordinate().getZ(); - const int index = (((xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3; - - const KernelCellClass* inter[343]; - memset(inter, 0, sizeof(KernelCellClass*)*343); - inter[index] = &cellSrc; - - kernelhandle->kernel[threadId]->M2L(&cellDst, inter, 1, level); - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_P2P_inner(void *fmmCore, void *boxIdSrcDest){ - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FReal* positionsTargets; - FReal* potentialsTargets; - int numberTargets; - FmmCore_getSource(fmmCore, boxIdSrcDest, &positionsTargets, (void**)&potentialsTargets, &numberTargets); - - FReal* fieldsTargets = new FReal[numberTargets*kernelhandle->fieldDataSize]; - FmmCore_getTargetField(fmmCore, boxIdSrcDest, fieldsTargets); - - int coordTargets[3]; - FmmCore_getCoord(fmmCore, boxIdSrcDest, coordTargets); - FTreeCoordinate treecoord(coordTargets[0], coordTargets[1], coordTargets[2]); - - FP2PParticleContainer targets; - for(FSize idxPart = 0 ; idxPart < numberTargets ; ++idxPart){ - targets.push(FPoint(positionsTargets[idxPart*3],positionsTargets[idxPart*3+1],positionsTargets[idxPart*3+2]), - potentialsTargets[idxPart], - fieldsTargets[idxPart*kernelhandle->fieldDataSize], - fieldsTargets[idxPart*kernelhandle->fieldDataSize+1], - fieldsTargets[idxPart*kernelhandle->fieldDataSize+2], - fieldsTargets[idxPart*kernelhandle->fieldDataSize+3]); - } - - - FP2PParticleContainer* ptrs[27]; - memset(ptrs, 0, sizeof(FP2PParticleContainer*) * 27); - kernelhandle->kernel[threadId]->P2P(treecoord, &targets, &targets, ptrs, 0); - - const FReal*const potentials = targets.getPotentials(); - const FReal*const forcesX = targets.getForcesX(); - const FReal*const forcesY = targets.getForcesY(); - const FReal*const forcesZ = targets.getForcesZ(); - - for(FSize idxPart = 0 ; idxPart < numberTargets ; ++idxPart){ - fieldsTargets[idxPart*kernelhandle->fieldDataSize] = potentials[idxPart]; - fieldsTargets[idxPart*kernelhandle->fieldDataSize+1] = forcesX[idxPart]; - fieldsTargets[idxPart*kernelhandle->fieldDataSize+2] = forcesY[idxPart]; - fieldsTargets[idxPart*kernelhandle->fieldDataSize+3] = forcesZ[idxPart]; - } - - FmmCore_releaseTargetPoints(fmmCore, boxIdSrcDest, positionsTargets); - FmmCore_setTargetField(fmmCore, boxIdSrcDest, fieldsTargets); - delete[] fieldsTargets; - - return FMMAPI_NO_ERROR; -} - -int FmmKernel_P2P(void *fmmCore, void *boxIdSrc, void *boxIdDest){ //return FMMAPI_NO_ERROR; - ScalFmmKernelHandle* kernelhandle; - FmmCore_getKernelData(fmmCore, (void**)&kernelhandle); - int threadId; - FmmCore_getParameter(fmmCore, FMMCORE_THREAD_ID, &threadId); - - FReal* positionsTargets; - FReal* potentialsTargets; - int numberTargets; - FmmCore_getSource(fmmCore, boxIdDest, &positionsTargets, (void**)&potentialsTargets, &numberTargets); - - FReal* fieldsTargets = new FReal[numberTargets*kernelhandle->fieldDataSize]; - FmmCore_getTargetField(fmmCore, boxIdDest, fieldsTargets); - - int coordTargets[3]; - FmmCore_getCoord(fmmCore, boxIdDest, coordTargets); - FTreeCoordinate treecoord(coordTargets[0], coordTargets[1], coordTargets[2]); - - FP2PParticleContainer targets; - for(FSize idxPart = 0 ; idxPart < numberTargets ; ++idxPart){ - targets.push(FPoint(positionsTargets[idxPart*3],positionsTargets[idxPart*3+1],positionsTargets[idxPart*3+2]), - potentialsTargets[idxPart], - fieldsTargets[idxPart*kernelhandle->fieldDataSize], - fieldsTargets[idxPart*kernelhandle->fieldDataSize+1], - fieldsTargets[idxPart*kernelhandle->fieldDataSize+2], - fieldsTargets[idxPart*kernelhandle->fieldDataSize+3]); - } - - FReal* positionsSrc; - FReal* potentialsSrc; - int numberSources; - FmmCore_getSource(fmmCore, boxIdSrc, &positionsSrc, (void**)&potentialsSrc, &numberSources); - - FP2PParticleContainer sources; - for(FSize idxPart = 0 ; idxPart < numberSources ; ++idxPart){ - sources.push(FPoint(positionsSrc[idxPart*3],positionsSrc[idxPart*3+1],positionsSrc[idxPart*3+2]),potentialsSrc[idxPart]); - } - - FP2PParticleContainer* ptrs[27]; - memset(ptrs, 0, sizeof(FP2PParticleContainer*) * 27); - ptrs[0] = &sources; - kernelhandle->kernel[threadId]->P2PRemote(treecoord, &targets, &targets, ptrs, 1); - - const FReal*const potentials = targets.getPotentials(); - const FReal*const forcesX = targets.getForcesX(); - const FReal*const forcesY = targets.getForcesY(); - const FReal*const forcesZ = targets.getForcesZ(); - - for(FSize idxPart = 0 ; idxPart < numberTargets ; ++idxPart){ - fieldsTargets[idxPart*kernelhandle->fieldDataSize] = potentials[idxPart]; - fieldsTargets[idxPart*kernelhandle->fieldDataSize+1] = forcesX[idxPart]; - fieldsTargets[idxPart*kernelhandle->fieldDataSize+2] = forcesY[idxPart]; - fieldsTargets[idxPart*kernelhandle->fieldDataSize+3] = forcesZ[idxPart]; - } - - FmmCore_releaseSource(fmmCore, boxIdDest, potentialsSrc, positionsSrc); - FmmCore_releaseTargetPoints(fmmCore, boxIdDest, positionsTargets); - FmmCore_setTargetField(fmmCore, boxIdDest, fieldsTargets); - delete[] fieldsTargets; - - return FMMAPI_NO_ERROR; -} /* pas mutuel, i.e. on fait seulement dans 1 sens. */ - - diff --git a/Addons/FmmApi/Tests/testFmmApi.cpp b/Addons/FmmApi/Tests/testFmmApi.cpp deleted file mode 100644 index ae699f5d368873395da7d38c4763d5546535cafd..0000000000000000000000000000000000000000 --- a/Addons/FmmApi/Tests/testFmmApi.cpp +++ /dev/null @@ -1,193 +0,0 @@ -// =================================================================================== -// Logiciel initial: ScalFmm Version 0.5 -// Co-auteurs : Olivier Coulaud, Bérenger Bramas. -// Propriétaires : INRIA. -// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire. -// Initial software: ScalFmm Version 0.5 -// Co-authors: Olivier Coulaud, Bérenger Bramas. -// Owners: INRIA. -// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license. -// =================================================================================== - -#include -#include - -#include "../../Src/Utils/FParameters.hpp" -#include "../../Src/Utils/FTic.hpp" -#include "../../Src/Utils/FMemUtils.hpp" - -#include "../../Src/Files/FRandomLoader.hpp" - -#include "../Src/FmmApi.h" - -/** This program show an example of use of the fmm api - */ - -// Simply create particles and try the kernels -int main(int argc, char ** argv){ - ///////////////////////What we do///////////////////////////// - std::cout << ">> This executable has to be used to test the FMM API\n"; - ////////////////////////////////////////////////////////////// - - int NbLevels = FParameters::getValue(argc,argv,"-h", 7); - int SizeSubLevels = FParameters::getValue(argc,argv,"-sh", 3); - const int NbPart = FParameters::getValue(argc,argv,"-nb", 2000000); - FTic counter; - - ////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1); - - void* FmmCoreHandle; - FmmCore_init(&FmmCoreHandle); - - FmmCore_setParameter(FmmCoreHandle, FMMCORE_TREE_HEIGHT, &NbLevels); - FReal boxWidth = loader.getBoxWidth(); - FmmCore_setParameter(FmmCoreHandle, FMMCORE_ROOT_BOX_WIDTH, &boxWidth); - FmmCore_setParameter(FmmCoreHandle, FMMCORE_ROOT_BOX_CENTER, loader.getCenterOfBox().getDataValue()); - - void* FmmKernelHandle; - FmmKernel_init(FmmCoreHandle, &FmmKernelHandle); - - FmmCore_setKernelData(FmmCoreHandle, FmmKernelHandle); - - ////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - std::cout << "Creating & Inserting " << NbPart << " particles ..." << std::endl; - std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl; - counter.tic(); - - FSize r.getNumberOfParticles(); - FReal* potentials = new FReal[nbPart]; - FReal* positions = new FReal[nbPart*3]; - - { - FPoint part; - const FReal physicalValue = 0.1; - - for(int idx = 0 ; idx < nbPart ; ++idx){ - loader.fillParticle(&part); - - potentials[idx] = physicalValue; - positions[3*idx] = part.getX(); - positions[3*idx+1] = part.getY(); - positions[3*idx+2] = part.getZ(); - } - - FmmCore_setPositions(FmmCoreHandle, &nbPart, positions); - FmmCore_setPotentials(FmmCoreHandle, potentials); - } - - counter.tac(); - std::cout << "Done " << "(@Creating and Inserting Particles = " << counter.elapsed() << "s)." << std::endl; - - ////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - std::cout << "Working on particles ..." << std::endl; - counter.tic(); - - FmmCore_doComputation(FmmCoreHandle); - - counter.tac(); - std::cout << "Done " << "(@Algorithm = " << counter.elapsed() << "s)." << std::endl; - - ////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - std::cout << "Getting results ..." << std::endl; - counter.tic(); - - FReal* fields = new FReal[4*nbPart]; - - FmmCore_getField(FmmCoreHandle, fields); - - counter.tac(); - std::cout << "Done " << "(@retrieve = " << counter.elapsed() << "s)." << std::endl; - - ////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - std::cout << "Computing direct ..." << std::endl; - counter.tic(); - - FReal* fieldsdirect = new FReal[4*nbPart]; - FMemUtils::setall(fieldsdirect, 0.0, nbPart * 4); - - for(int idxTarget = 0 ; idxTarget < nbPart ; ++idxTarget){ - - for(int idxSource = idxTarget + 1 ; idxSource < nbPart ; ++idxSource){ - FReal dx = positions[idxSource*3] - positions[idxTarget*3]; - FReal dy = positions[idxSource*3+1] - positions[idxTarget*3+1]; - FReal dz = positions[idxSource*3+2] - positions[idxTarget*3+2]; - - FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz); - FReal inv_distance = FMath::Sqrt(inv_square_distance); - - inv_square_distance *= inv_distance; - inv_square_distance *= potentials[idxTarget] * potentials[idxSource]; - - dx *= inv_square_distance; - dy *= inv_square_distance; - dz *= inv_square_distance; - - fieldsdirect[4*idxTarget+1] += dx; - fieldsdirect[4*idxTarget+2] += dy; - fieldsdirect[4*idxTarget+3] += dz; - fieldsdirect[4*idxTarget+0] += inv_distance * potentials[idxSource]; - - fieldsdirect[4*idxSource+1] += -dx; - fieldsdirect[4*idxSource+2] += -dy; - fieldsdirect[4*idxSource+3] += -dz; - fieldsdirect[4*idxSource+0] += inv_distance * potentials[idxTarget]; - - } - } - - - counter.tac(); - std::cout << "Done " << "(@direct = " << counter.elapsed() << "s)." << std::endl; - - ////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - - std::cout << "Comparing results ..." << std::endl; - counter.tic(); - - FMath::FAccurater forces; - FMath::FAccurater potential; - - for(int idx = 0 ; idx < nbPart ; ++idx){ - if(idx < 10){ - std::cout << fieldsdirect[4*idx] << " fmm " << fields[4*idx] << std::endl; - } - forces.add( fieldsdirect[4*idx] ,fields[4*idx]); - forces.add( fieldsdirect[4*idx+1] ,fields[4*idx+1]); - forces.add( fieldsdirect[4*idx+2] ,fields[4*idx+2]); - potential.add( fieldsdirect[4*idx+3] ,fields[4*idx+3]); - } - - counter.tac(); - std::cout << "Done " << "(@comparing = " << counter.elapsed() << "s)." << std::endl; - - std::cout << "\tForces inf " << forces.getInfNorm() << " normL2 " << forces.getL2Norm() << std::endl; - std::cout << "\tPotential inf " << potential.getInfNorm() << " normL2 " << potential.getL2Norm() << std::endl; - - ////////////////////////////////////////////////////////////////////////////////// - - delete[] fieldsdirect; - delete[] fields; - delete[] potentials; - delete[] positions; - - FmmCore_free(FmmCoreHandle); - FmmKernel_free(FmmKernelHandle); - - return 0; -} - - - diff --git a/Addons/HMat/CClusteringLibrary/COPYING b/Addons/HMat/CClusteringLibrary/COPYING deleted file mode 100644 index 69b2aff860515a3b5cb3c117095aa1086f299f61..0000000000000000000000000000000000000000 --- a/Addons/HMat/CClusteringLibrary/COPYING +++ /dev/null @@ -1,19 +0,0 @@ -License Information -=================== - -The Open Source Clustering Software consists of several packages, which have -different licenses. - -* Cluster 3.0 is a GUI-based program for Windows, Mac OS X, Linux, and Unix. - It is based on Michael Eisen's Cluster/TreeView code. Cluster 3.0 is covered - by Michael Eisen's original license, available at - http://rana.lbl.gov/EisenSoftwareSource.htm. The command-line version of - Cluster 3.0 is also covered by this license. -* Pycluster is an extension module to the scripting language Python. It is - covered by the Python License (same license as Python itself). -* Algorithm::Cluster, the interface to the scripting language Perl. It was - released under the Artistic License (same license as Perl itself). -* The routines in the C Clustering Library can also be used directly by calling - them from other C programs. In that case, the Python License applies. - -In all cases, copyright notices must be retained in their original form. diff --git a/Addons/HMat/CClusteringLibrary/README b/Addons/HMat/CClusteringLibrary/README deleted file mode 100644 index 5186e312cf05c9eb0aacfb2c2a953ba68a9ec9bc..0000000000000000000000000000000000000000 --- a/Addons/HMat/CClusteringLibrary/README +++ /dev/null @@ -1,68 +0,0 @@ -Open Source Clustering Software -=============================== - -The Open Source Clustering Software consists of the most commonly used routines -for clustering analysis of gene expression data. The software packages below all -depend on the C Clustering Library, which is a library of routines for -hierarchical (pairwise single-, complete-, maximum-, and average-linkage) -clustering, k-means clustering, and Self-Organizing Maps on a 2D rectangular -grid. The C Clustering Library complies with the ANSI C standard. - -Several packages are available as part of the Open Source Clustering Software: -* Cluster 3.0 is a GUI-based program for Windows, based on Michael Eisen's - Cluster/TreeView code. Cluster 3.0 was written for Microsoft Windows, and - subsequently ported to Mac OS X (Cocoa) and Unix/Linux. Cluster 3.0 can - also be used as a command line program. -* Pycluster (or Bio.Cluster if used as part of Biopython) is an extension - module to the scripting language Python. -* Algorithm::Cluster is an extension module to the scripting language Perl. -* The routines in the C Clustering Library can also be used directly by calling - them from other C programs. - - -INSTALLATION -============ - -See the INSTALL file in this directory. - - -VIEWING CLUSTERING RESULTS -========================== - -We recommend using Java TreeView for visualizing clustering results. -Java TreeView is a Java version of Michael Eisen's Treeview program with -extended capabilities. In particular, it is possible to visualize k-means -clustering results in addition to hierarchical clustering results. - -Java TreeView was written by Alok Saldanha at Stanford University; it can be -downloaded at http://jtreeview.sourceforge.net. - - -MANUAL -====== - -The routines in the C Clustering Library is described in the manual -(cluster.pdf). This manual also describes how to use the routines from Python -and from Perl. Cluster 3.0 has a separate manual (cluster3.pdf). Both of these -manuals can be found in the doc subdirectory. They can also be downloaded from -our website: -http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster.pdf; -http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/cluster3.pdf. - - -LITERATURE -========== - -M.J.L. de Hoon, S. Imoto, J. Nolan, and S. Miyano: "Open Source Clustering -Software", Bioinformatics 20(9): 1453-1454 (2004). - - -CONTACT -======= - -Michiel de Hoon -University of Tokyo, Institute of Medical Science -Human Genome Center, Laboratory of DNA Information Analysis -Currently at -RIKEN Genomic Sciences Center -mdehoon 'AT' gsc.riken.jp diff --git a/Addons/HMat/CClusteringLibrary/cluster.c b/Addons/HMat/CClusteringLibrary/cluster.c deleted file mode 100644 index f9213e93c7cb9b02a7c21056dea74a206b53da23..0000000000000000000000000000000000000000 --- a/Addons/HMat/CClusteringLibrary/cluster.c +++ /dev/null @@ -1,4608 +0,0 @@ -/* The C clustering library. - * Copyright (C) 2002 Michiel Jan Laurens de Hoon. - * - * This library was written at the Laboratory of DNA Information Analysis, - * Human Genome Center, Institute of Medical Science, University of Tokyo, - * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. - * Contact: mdehoon 'AT' gsc.riken.jp - * - * Permission to use, copy, modify, and distribute this software and its - * documentation with or without modifications and for any purpose and - * without fee is hereby granted, provided that any copyright notices - * appear in all copies and that both those copyright notices and this - * permission notice appear in supporting documentation, and that the - * names of the contributors or copyright holders not be used in - * advertising or publicity pertaining to distribution of the software - * without specific prior permission. - * - * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE - * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT - * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE - * OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -// @SCALFMM_PRIVATE - -#include -#include -#include -#include -#include -#include -#include "cluster.h" -#ifdef WINDOWS -# include -#endif - - -#ifndef ccl_min -#define ccl_min(x, y) ((x) < (y) ? (x) : (y)) -#endif -#ifndef ccl_max -#define ccl_max(x, y) ((x) > (y) ? (x) : (y)) -#endif - -/* ************************************************************************ */ - -#ifdef WINDOWS -/* Then we make a Windows DLL */ -int WINAPI -clusterdll_init (HANDLE h, DWORD reason, void* foo) -{ - return 1; -} -#endif - -/* ************************************************************************ */ - -double mean(int n, double x[]) -{ double result = 0.; - int i; - for (i = 0; i < n; i++) result += x[i]; - result /= n; - return result; -} - -/* ************************************************************************ */ - -double median (int n, double x[]) -/* -Find the median of X(1), ... , X(N), using as much of the quicksort -algorithm as is needed to isolate it. -N.B. On exit, the array X is partially ordered. -Based on Alan J. Miller's median.f90 routine. -*/ - -{ int i, j; - int nr = n / 2; - int nl = nr - 1; - int even = 0; - /* hi & lo are position limits encompassing the median. */ - int lo = 0; - int hi = n-1; - - if (n==2*nr) even = 1; - if (n<3) - { if (n<1) return 0.; - if (n == 1) return x[0]; - return 0.5*(x[0]+x[1]); - } - - /* Find median of 1st, middle & last values. */ - do - { int loop; - int mid = (lo + hi)/2; - double result = x[mid]; - double xlo = x[lo]; - double xhi = x[hi]; - if (xhixhi) result = xhi; - else if (resultresult) j--; - loop = 0; - if (inr) hi = j; - if (i==j) - { if (i==nl) lo = nl; - if (j==nr) hi = nr; - } - } - else - { if (jnr) hi = j; - /* Test whether median has been isolated. */ - if (i==j && i==nr) return result; - } - } - while (lox[hi]) - { double temp = x[lo]; - x[lo] = x[hi]; - x[hi] = temp; - } - return x[nr]; -} - -/* ********************************************************************** */ - -static const double* sortdata = NULL; /* used in the quicksort algorithm */ - -/* ---------------------------------------------------------------------- */ - -static -int compare(const void* a, const void* b) -/* Helper function for sort. Previously, this was a nested function under - * sort, which is not allowed under ANSI C. - */ -{ const int i1 = *(const int*)a; - const int i2 = *(const int*)b; - const double term1 = sortdata[i1]; - const double term2 = sortdata[i2]; - if (term1 < term2) return -1; - if (term1 > term2) return +1; - return 0; -} - -/* ---------------------------------------------------------------------- */ - -void sort(int n, const double data[], int index[]) -/* Sets up an index table given the data, such that data[index[]] is in - * increasing order. Sorting is done on the indices; the array data - * is unchanged. - */ -{ int i; - sortdata = data; - for (i = 0; i < n; i++) index[i] = i; - qsort(index, n, sizeof(int), compare); -} - -/* ********************************************************************** */ - -static double* getrank (int n, double data[]) -/* Calculates the ranks of the elements in the array data. Two elements with - * the same value get the same rank, equal to the average of the ranks had the - * elements different values. The ranks are returned as a newly allocated - * array that should be freed by the calling routine. If getrank fails due to - * a memory allocation error, it returns NULL. - */ -{ int i; - double* rank; - int* index; - rank = malloc(n*sizeof(double)); - if (!rank) return NULL; - index = malloc(n*sizeof(int)); - if (!index) - { free(rank); - return NULL; - } - /* Call sort to get an index table */ - sort (n, data, index); - /* Build a rank table */ - for (i = 0; i < n; i++) rank[index[i]] = i; - /* Fix for equal ranks */ - i = 0; - while (i < n) - { int m; - double value = data[index[i]]; - int j = i + 1; - while (j < n && data[index[j]] == value) j++; - m = j - i; /* number of equal ranks found */ - value = rank[index[i]] + (m-1)/2.; - for (j = i; j < i + m; j++) rank[index[j]] = value; - i += m; - } - free (index); - return rank; -} - -/* ---------------------------------------------------------------------- */ - -static int -makedatamask(int nrows, int ncols, double*** pdata, int*** pmask) -{ int i; - double** data; - int** mask; - data = malloc(nrows*sizeof(double*)); - if(!data) return 0; - mask = malloc(nrows*sizeof(int*)); - if(!mask) - { free(data); - return 0; - } - for (i = 0; i < nrows; i++) - { data[i] = malloc(ncols*sizeof(double)); - if(!data[i]) break; - mask[i] = malloc(ncols*sizeof(int)); - if(!mask[i]) - { free(data[i]); - break; - } - } - if (i==nrows) /* break not encountered */ - { *pdata = data; - *pmask = mask; - return 1; - } - *pdata = NULL; - *pmask = NULL; - nrows = i; - for (i = 0; i < nrows; i++) - { free(data[i]); - free(mask[i]); - } - free(data); - free(mask); - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static void -freedatamask(int n, double** data, int** mask) -{ int i; - for (i = 0; i < n; i++) - { free(mask[i]); - free(data[i]); - } - free(mask); - free(data); -} - -/* ---------------------------------------------------------------------- */ - -static -double find_closest_pair(int n, double** distmatrix, int* ip, int* jp) -/* -This function searches the distance matrix to find the pair with the shortest -distance between them. The indices of the pair are returned in ip and jp; the -distance itself is returned by the function. - -n (input) int -The number of elements in the distance matrix. - -distmatrix (input) double** -A ragged array containing the distance matrix. The number of columns in each -row is one less than the row index. - -ip (output) int* -A pointer to the integer that is to receive the first index of the pair with -the shortest distance. - -jp (output) int* -A pointer to the integer that is to receive the second index of the pair with -the shortest distance. -*/ -{ int i, j; - double temp; - double distance = distmatrix[1][0]; - *ip = 1; - *jp = 0; - for (i = 1; i < n; i++) - { for (j = 0; j < i; j++) - { temp = distmatrix[i][j]; - if (temp= n) - { /* Householder reduction to bidiagonal form */ - for (i = 0; i < n; i++) - { l = i + 1; - rv1[i] = scale * g; - g = 0.0; - s = 0.0; - scale = 0.0; - for (k = i; k < m; k++) scale += fabs(u[k][i]); - if (scale != 0.0) - { for (k = i; k < m; k++) - { u[k][i] /= scale; - s += u[k][i]*u[k][i]; - } - f = u[i][i]; - g = (f >= 0) ? -sqrt(s) : sqrt(s); - h = f * g - s; - u[i][i] = f - g; - if (i < n-1) - { for (j = l; j < n; j++) - { s = 0.0; - for (k = i; k < m; k++) s += u[k][i] * u[k][j]; - f = s / h; - for (k = i; k < m; k++) u[k][j] += f * u[k][i]; - } - } - for (k = i; k < m; k++) u[k][i] *= scale; - } - w[i] = scale * g; - g = 0.0; - s = 0.0; - scale = 0.0; - if (i= 0) ? -sqrt(s) : sqrt(s); - h = f * g - s; - u[i][l] = f - g; - for (k = l; k < n; k++) rv1[k] = u[i][k] / h; - for (j = l; j < m; j++) - { s = 0.0; - for (k = l; k < n; k++) s += u[j][k] * u[i][k]; - for (k = l; k < n; k++) u[j][k] += s * rv1[k]; - } - for (k = l; k < n; k++) u[i][k] *= scale; - } - } - anorm = ccl_max(anorm,fabs(w[i])+fabs(rv1[i])); - } - /* accumulation of right-hand transformations */ - for (i = n-1; i>=0; i--) - { if (i < n-1) - { if (g != 0.0) - { for (j = l; j < n; j++) vt[i][j] = (u[i][j] / u[i][l]) / g; - /* double division avoids possible underflow */ - for (j = l; j < n; j++) - { s = 0.0; - for (k = l; k < n; k++) s += u[i][k] * vt[j][k]; - for (k = l; k < n; k++) vt[j][k] += s * vt[i][k]; - } - } - } - for (j = l; j < n; j++) - { vt[j][i] = 0.0; - vt[i][j] = 0.0; - } - vt[i][i] = 1.0; - g = rv1[i]; - l = i; - } - /* accumulation of left-hand transformations */ - for (i = n-1; i >= 0; i--) - { l = i + 1; - g = w[i]; - if (i!=n-1) - for (j = l; j < n; j++) u[i][j] = 0.0; - if (g!=0.0) - { if (i!=n-1) - { for (j = l; j < n; j++) - { s = 0.0; - for (k = l; k < m; k++) s += u[k][i] * u[k][j]; - /* double division avoids possible underflow */ - f = (s / u[i][i]) / g; - for (k = i; k < m; k++) u[k][j] += f * u[k][i]; - } - } - for (j = i; j < m; j++) u[j][i] /= g; - } - else - for (j = i; j < m; j++) u[j][i] = 0.0; - u[i][i] += 1.0; - } - /* diagonalization of the bidiagonal form */ - for (k = n-1; k >= 0; k--) - { k1 = k-1; - its = 0; - while(1) - /* test for splitting */ - { for (l = k; l >= 0; l--) - { l1 = l-1; - if (fabs(rv1[l]) + anorm == anorm) break; - /* rv1[0] is always zero, so there is no exit - * through the bottom of the loop */ - if (fabs(w[l1]) + anorm == anorm) - /* cancellation of rv1[l] if l greater than 0 */ - { c = 0.0; - s = 1.0; - for (i = l; i <= k; i++) - { f = s * rv1[i]; - rv1[i] *= c; - if (fabs(f) + anorm == anorm) break; - g = w[i]; - h = sqrt(f*f+g*g); - w[i] = h; - c = g / h; - s = -f / h; - for (j = 0; j < m; j++) - { y = u[j][l1]; - z = u[j][i]; - u[j][l1] = y * c + z * s; - u[j][i] = -y * s + z * c; - } - } - break; - } - } - /* test for convergence */ - z = w[k]; - if (l==k) /* convergence */ - { if (z < 0.0) - /* w[k] is made non-negative */ - { w[k] = -z; - for (j = 0; j < n; j++) vt[k][j] = -vt[k][j]; - } - break; - } - else if (its==30) - { ierr = k; - break; - } - else - /* shift from bottom 2 by 2 minor */ - { its++; - x = w[l]; - y = w[k1]; - g = rv1[k1]; - h = rv1[k]; - f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); - g = sqrt(f*f+1.0); - f = ((x - z) * (x + z) + h * (y / (f + (f >= 0 ? g : -g)) - h)) / x; - /* next qr transformation */ - c = 1.0; - s = 1.0; - for (i1 = l; i1 <= k1; i1++) - { i = i1 + 1; - g = rv1[i]; - y = w[i]; - h = s * g; - g = c * g; - z = sqrt(f*f+h*h); - rv1[i1] = z; - c = f / z; - s = h / z; - f = x * c + g * s; - g = -x * s + g * c; - h = y * s; - y = y * c; - for (j = 0; j < n; j++) - { x = vt[i1][j]; - z = vt[i][j]; - vt[i1][j] = x * c + z * s; - vt[i][j] = -x * s + z * c; - } - z = sqrt(f*f+h*h); - w[i1] = z; - /* rotation can be arbitrary if z is zero */ - if (z!=0.0) - { c = f / z; - s = h / z; - } - f = c * g + s * y; - x = -s * g + c * y; - for (j = 0; j < m; j++) - { y = u[j][i1]; - z = u[j][i]; - u[j][i1] = y * c + z * s; - u[j][i] = -y * s + z * c; - } - } - rv1[l] = 0.0; - rv1[k] = f; - w[k] = x; - } - } - } - } - else /* m < n */ - { /* Householder reduction to bidiagonal form */ - for (i = 0; i < m; i++) - { l = i + 1; - rv1[i] = scale * g; - g = 0.0; - s = 0.0; - scale = 0.0; - for (k = i; k < n; k++) scale += fabs(u[i][k]); - if (scale != 0.0) - { for (k = i; k < n; k++) - { u[i][k] /= scale; - s += u[i][k]*u[i][k]; - } - f = u[i][i]; - g = (f >= 0) ? -sqrt(s) : sqrt(s); - h = f * g - s; - u[i][i] = f - g; - if (i < m-1) - { for (j = l; j < m; j++) - { s = 0.0; - for (k = i; k < n; k++) s += u[i][k] * u[j][k]; - f = s / h; - for (k = i; k < n; k++) u[j][k] += f * u[i][k]; - } - } - for (k = i; k < n; k++) u[i][k] *= scale; - } - w[i] = scale * g; - g = 0.0; - s = 0.0; - scale = 0.0; - if (i= 0) ? -sqrt(s) : sqrt(s); - h = f * g - s; - u[l][i] = f - g; - for (k = l; k < m; k++) rv1[k] = u[k][i] / h; - for (j = l; j < n; j++) - { s = 0.0; - for (k = l; k < m; k++) s += u[k][j] * u[k][i]; - for (k = l; k < m; k++) u[k][j] += s * rv1[k]; - } - for (k = l; k < m; k++) u[k][i] *= scale; - } - } - anorm = ccl_max(anorm,fabs(w[i])+fabs(rv1[i])); - } - /* accumulation of right-hand transformations */ - for (i = m-1; i>=0; i--) - { if (i < m-1) - { if (g != 0.0) - { for (j = l; j < m; j++) vt[j][i] = (u[j][i] / u[l][i]) / g; - /* double division avoids possible underflow */ - for (j = l; j < m; j++) - { s = 0.0; - for (k = l; k < m; k++) s += u[k][i] * vt[k][j]; - for (k = l; k < m; k++) vt[k][j] += s * vt[k][i]; - } - } - } - for (j = l; j < m; j++) - { vt[i][j] = 0.0; - vt[j][i] = 0.0; - } - vt[i][i] = 1.0; - g = rv1[i]; - l = i; - } - /* accumulation of left-hand transformations */ - for (i = m-1; i >= 0; i--) - { l = i + 1; - g = w[i]; - if (i!=m-1) - for (j = l; j < m; j++) u[j][i] = 0.0; - if (g!=0.0) - { if (i!=m-1) - { for (j = l; j < m; j++) - { s = 0.0; - for (k = l; k < n; k++) s += u[i][k] * u[j][k]; - /* double division avoids possible underflow */ - f = (s / u[i][i]) / g; - for (k = i; k < n; k++) u[j][k] += f * u[i][k]; - } - } - for (j = i; j < n; j++) u[i][j] /= g; - } - else - for (j = i; j < n; j++) u[i][j] = 0.0; - u[i][i] += 1.0; - } - /* diagonalization of the bidiagonal form */ - for (k = m-1; k >= 0; k--) - { k1 = k-1; - its = 0; - while(1) - /* test for splitting */ - { for (l = k; l >= 0; l--) - { l1 = l-1; - if (fabs(rv1[l]) + anorm == anorm) break; - /* rv1[0] is always zero, so there is no exit - * through the bottom of the loop */ - if (fabs(w[l1]) + anorm == anorm) - /* cancellation of rv1[l] if l greater than 0 */ - { c = 0.0; - s = 1.0; - for (i = l; i <= k; i++) - { f = s * rv1[i]; - rv1[i] *= c; - if (fabs(f) + anorm == anorm) break; - g = w[i]; - h = sqrt(f*f+g*g); - w[i] = h; - c = g / h; - s = -f / h; - for (j = 0; j < n; j++) - { y = u[l1][j]; - z = u[i][j]; - u[l1][j] = y * c + z * s; - u[i][j] = -y * s + z * c; - } - } - break; - } - } - /* test for convergence */ - z = w[k]; - if (l==k) /* convergence */ - { if (z < 0.0) - /* w[k] is made non-negative */ - { w[k] = -z; - for (j = 0; j < m; j++) vt[j][k] = -vt[j][k]; - } - break; - } - else if (its==30) - { ierr = k; - break; - } - else - /* shift from bottom 2 by 2 minor */ - { its++; - x = w[l]; - y = w[k1]; - g = rv1[k1]; - h = rv1[k]; - f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); - g = sqrt(f*f+1.0); - f = ((x - z) * (x + z) + h * (y / (f + (f >= 0 ? g : -g)) - h)) / x; - /* next qr transformation */ - c = 1.0; - s = 1.0; - for (i1 = l; i1 <= k1; i1++) - { i = i1 + 1; - g = rv1[i]; - y = w[i]; - h = s * g; - g = c * g; - z = sqrt(f*f+h*h); - rv1[i1] = z; - c = f / z; - s = h / z; - f = x * c + g * s; - g = -x * s + g * c; - h = y * s; - y = y * c; - for (j = 0; j < m; j++) - { x = vt[j][i1]; - z = vt[j][i]; - vt[j][i1] = x * c + z * s; - vt[j][i] = -x * s + z * c; - } - z = sqrt(f*f+h*h); - w[i1] = z; - /* rotation can be arbitrary if z is zero */ - if (z!=0.0) - { c = f / z; - s = h / z; - } - f = c * g + s * y; - x = -s * g + c * y; - for (j = 0; j < n; j++) - { y = u[i1][j]; - z = u[i][j]; - u[i1][j] = y * c + z * s; - u[i][j] = -y * s + z * c; - } - } - rv1[l] = 0.0; - rv1[k] = f; - w[k] = x; - } - } - } - } - free(rv1); - return ierr; -} - -/* ********************************************************************* */ - -int pca(int nrows, int ncolumns, double** u, double** v, double* w) -/* -Purpose -======= - -This subroutine uses the singular value decomposition to perform principal -components analysis of a real nrows by ncolumns rectangular matrix. - -Arguments -========= - -nrows (input) int -The number of rows in the matrix u. - -ncolumns (input) int -The number of columns in the matrix v. - -u (input) double[nrows][ncolumns] -On input, the array containing the data to which the principal component -analysis should be applied. The function assumes that the mean has already been -subtracted of each column, and hence that the mean of each column is zero. -On output, see below. - -v (input) double[n][n], where n = min(nrows, ncolumns) -Not used on input. - -w (input) double[n], where n = min(nrows, ncolumns) -Not used on input. - - -Return value -============ - -On output: - -If nrows >= ncolumns, then - -u contains the coordinates with respect to the principal components; -v contains the principal component vectors. - -The dot product u . v reproduces the data that were passed in u. - - -If nrows < ncolumns, then - -u contains the principal component vectors; -v contains the coordinates with respect to the principal components. - -The dot product v . u reproduces the data that were passed in u. - -The eigenvalues of the covariance matrix are returned in w. - -The arrays u, v, and w are sorted according to eigenvalue, with the largest -eigenvalues appearing first. - -The function returns 0 if successful, -1 if memory allocation fails, and a -positive integer if the singular value decomposition fails to converge. -*/ -{ - int i; - int j; - int error; - int* index = malloc(ncolumns*sizeof(int)); - double* temp = malloc(ncolumns*sizeof(double)); - if (!index || !temp) - { if (index) free(index); - if (temp) free(temp); - return -1; - } - error = svd(nrows, ncolumns, u, w, v); - if (error==0) - { - if (nrows >= ncolumns) - { for (j = 0; j < ncolumns; j++) - { const double s = w[j]; - for (i = 0; i < nrows; i++) u[i][j] *= s; - } - sort(ncolumns, w, index); - for (i = 0; i < ncolumns/2; i++) - { j = index[i]; - index[i] = index[ncolumns-1-i]; - index[ncolumns-1-i] = j; - } - for (i = 0; i < nrows; i++) - { for (j = 0; j < ncolumns; j++) temp[j] = u[i][index[j]]; - for (j = 0; j < ncolumns; j++) u[i][j] = temp[j]; - } - for (i = 0; i < ncolumns; i++) - { for (j = 0; j < ncolumns; j++) temp[j] = v[index[j]][i]; - for (j = 0; j < ncolumns; j++) v[j][i] = temp[j]; - } - for (i = 0; i < ncolumns; i++) temp[i] = w[index[i]]; - for (i = 0; i < ncolumns; i++) w[i] = temp[i]; - } - else /* nrows < ncolumns */ - { for (j = 0; j < nrows; j++) - { const double s = w[j]; - for (i = 0; i < nrows; i++) v[i][j] *= s; - } - sort(nrows, w, index); - for (i = 0; i < nrows/2; i++) - { j = index[i]; - index[i] = index[nrows-1-i]; - index[nrows-1-i] = j; - } - for (j = 0; j < ncolumns; j++) - { for (i = 0; i < nrows; i++) temp[i] = u[index[i]][j]; - for (i = 0; i < nrows; i++) u[i][j] = temp[i]; - } - for (j = 0; j < nrows; j++) - { for (i = 0; i < nrows; i++) temp[i] = v[j][index[i]]; - for (i = 0; i < nrows; i++) v[j][i] = temp[i]; - } - for (i = 0; i < nrows; i++) temp[i] = w[index[i]]; - for (i = 0; i < nrows; i++) w[i] = temp[i]; - } - } - free(index); - free(temp); - return error; -} - -/* ********************************************************************* */ - -static -double euclid (int n, double** data1, double** data2, int** mask1, int** mask2, - const double weight[], int index1, int index2, int transpose) - -/* -Purpose -======= - -The euclid routine calculates the weighted Euclidean distance between two -rows or columns in a matrix. - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. - -============================================================================ -*/ -{ double result = 0.; - double tweight = 0; - int i; - if (transpose==0) /* Calculate the distance between two rows */ - { for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { double term = data1[index1][i] - data2[index2][i]; - result += weight[i]*term*term; - tweight += weight[i]; - } - } - } - else - { for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { double term = data1[i][index1] - data2[i][index2]; - result += weight[i]*term*term; - tweight += weight[i]; - } - } - } - if (!tweight) return 0; /* usually due to empty clusters */ - result /= tweight; - return result; -} - -/* ********************************************************************* */ - -static -double cityblock (int n, double** data1, double** data2, int** mask1, - int** mask2, const double weight[], int index1, int index2, int transpose) - -/* -Purpose -======= - -The cityblock routine calculates the weighted "City Block" distance between -two rows or columns in a matrix. City Block distance is defined as the -absolute value of X1-X2 plus the absolute value of Y1-Y2 plus..., which is -equivalent to taking an "up and over" path. - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. - -============================================================================ */ -{ double result = 0.; - double tweight = 0; - int i; - if (transpose==0) /* Calculate the distance between two rows */ - { for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { double term = data1[index1][i] - data2[index2][i]; - result = result + weight[i]*fabs(term); - tweight += weight[i]; - } - } - } - else - { for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { double term = data1[i][index1] - data2[i][index2]; - result = result + weight[i]*fabs(term); - tweight += weight[i]; - } - } - } - if (!tweight) return 0; /* usually due to empty clusters */ - result /= tweight; - return result; -} - -/* ********************************************************************* */ - -static -double correlation (int n, double** data1, double** data2, int** mask1, - int** mask2, const double weight[], int index1, int index2, int transpose) -/* -Purpose -======= - -The correlation routine calculates the weighted Pearson distance between two -rows or columns in a matrix. We define the Pearson distance as one minus the -Pearson correlation. -This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. -but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold -(e.g., choose b = a + c). - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. -============================================================================ -*/ -{ double result = 0.; - double sum1 = 0.; - double sum2 = 0.; - double denom1 = 0.; - double denom2 = 0.; - double tweight = 0.; - if (transpose==0) /* Calculate the distance between two rows */ - { int i; - for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { double term1 = data1[index1][i]; - double term2 = data2[index2][i]; - double w = weight[i]; - sum1 += w*term1; - sum2 += w*term2; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - tweight += w; - } - } - } - else - { int i; - for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { double term1 = data1[i][index1]; - double term2 = data2[i][index2]; - double w = weight[i]; - sum1 += w*term1; - sum2 += w*term2; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - tweight += w; - } - } - } - if (!tweight) return 0; /* usually due to empty clusters */ - result -= sum1 * sum2 / tweight; - denom1 -= sum1 * sum1 / tweight; - denom2 -= sum2 * sum2 / tweight; - if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */ - if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */ - result = result / sqrt(denom1*denom2); - result = 1. - result; - return result; -} - -/* ********************************************************************* */ - -static -double acorrelation (int n, double** data1, double** data2, int** mask1, - int** mask2, const double weight[], int index1, int index2, int transpose) -/* -Purpose -======= - -The acorrelation routine calculates the weighted Pearson distance between two -rows or columns, using the absolute value of the correlation. -This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. -but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold -(e.g., choose b = a + c). - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. -============================================================================ -*/ -{ double result = 0.; - double sum1 = 0.; - double sum2 = 0.; - double denom1 = 0.; - double denom2 = 0.; - double tweight = 0.; - if (transpose==0) /* Calculate the distance between two rows */ - { int i; - for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { double term1 = data1[index1][i]; - double term2 = data2[index2][i]; - double w = weight[i]; - sum1 += w*term1; - sum2 += w*term2; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - tweight += w; - } - } - } - else - { int i; - for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { double term1 = data1[i][index1]; - double term2 = data2[i][index2]; - double w = weight[i]; - sum1 += w*term1; - sum2 += w*term2; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - tweight += w; - } - } - } - if (!tweight) return 0; /* usually due to empty clusters */ - result -= sum1 * sum2 / tweight; - denom1 -= sum1 * sum1 / tweight; - denom2 -= sum2 * sum2 / tweight; - if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */ - if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */ - result = fabs(result) / sqrt(denom1*denom2); - result = 1. - result; - return result; -} - -/* ********************************************************************* */ - -static -double ucorrelation (int n, double** data1, double** data2, int** mask1, - int** mask2, const double weight[], int index1, int index2, int transpose) -/* -Purpose -======= - -The ucorrelation routine calculates the weighted Pearson distance between two -rows or columns, using the uncentered version of the Pearson correlation. In the -uncentered Pearson correlation, a zero mean is used for both vectors even if -the actual mean is nonzero. -This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. -but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold -(e.g., choose b = a + c). - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. -============================================================================ -*/ -{ double result = 0.; - double denom1 = 0.; - double denom2 = 0.; - int flag = 0; - /* flag will remain zero if no nonzero combinations of mask1 and mask2 are - * found. - */ - if (transpose==0) /* Calculate the distance between two rows */ - { int i; - for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { double term1 = data1[index1][i]; - double term2 = data2[index2][i]; - double w = weight[i]; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - flag = 1; - } - } - } - else - { int i; - for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { double term1 = data1[i][index1]; - double term2 = data2[i][index2]; - double w = weight[i]; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - flag = 1; - } - } - } - if (!flag) return 0.; - if (denom1==0.) return 1.; - if (denom2==0.) return 1.; - result = result / sqrt(denom1*denom2); - result = 1. - result; - return result; -} - -/* ********************************************************************* */ - -static -double uacorrelation (int n, double** data1, double** data2, int** mask1, - int** mask2, const double weight[], int index1, int index2, int transpose) -/* -Purpose -======= - -The uacorrelation routine calculates the weighted Pearson distance between two -rows or columns, using the absolute value of the uncentered version of the -Pearson correlation. In the uncentered Pearson correlation, a zero mean is used -for both vectors even if the actual mean is nonzero. -This definition yields a semi-metric: d(a,b) >= 0, and d(a,b) = 0 iff a = b. -but the triangular inequality d(a,b) + d(b,c) >= d(a,c) does not hold -(e.g., choose b = a + c). - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. -============================================================================ -*/ -{ double result = 0.; - double denom1 = 0.; - double denom2 = 0.; - int flag = 0; - /* flag will remain zero if no nonzero combinations of mask1 and mask2 are - * found. - */ - if (transpose==0) /* Calculate the distance between two rows */ - { int i; - for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { double term1 = data1[index1][i]; - double term2 = data2[index2][i]; - double w = weight[i]; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - flag = 1; - } - } - } - else - { int i; - for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { double term1 = data1[i][index1]; - double term2 = data2[i][index2]; - double w = weight[i]; - result += w*term1*term2; - denom1 += w*term1*term1; - denom2 += w*term2*term2; - flag = 1; - } - } - } - if (!flag) return 0.; - if (denom1==0.) return 1.; - if (denom2==0.) return 1.; - result = fabs(result) / sqrt(denom1*denom2); - result = 1. - result; - return result; -} - -/* ********************************************************************* */ - -static -double spearman (int n, double** data1, double** data2, int** mask1, - int** mask2, const double weight[], int index1, int index2, int transpose) -/* -Purpose -======= - -The spearman routine calculates the Spearman distance between two rows or -columns. The Spearman distance is defined as one minus the Spearman rank -correlation. - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -These weights are ignored, but included for consistency with other distance -measures. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. -============================================================================ -*/ -{ int i; - int m = 0; - double* rank1; - double* rank2; - double result = 0.; - double denom1 = 0.; - double denom2 = 0.; - double avgrank; - double* tdata1; - double* tdata2; - tdata1 = malloc(n*sizeof(double)); - if(!tdata1) return 0.0; /* Memory allocation error */ - tdata2 = malloc(n*sizeof(double)); - if(!tdata2) /* Memory allocation error */ - { free(tdata1); - return 0.0; - } - if (transpose==0) - { for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { tdata1[m] = data1[index1][i]; - tdata2[m] = data2[index2][i]; - m++; - } - } - } - else - { for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { tdata1[m] = data1[i][index1]; - tdata2[m] = data2[i][index2]; - m++; - } - } - } - if (m==0) - { free(tdata1); - free(tdata2); - return 0; - } - rank1 = getrank(m, tdata1); - free(tdata1); - if(!rank1) - { free(tdata2); - return 0.0; /* Memory allocation error */ - } - rank2 = getrank(m, tdata2); - free(tdata2); - if(!rank2) /* Memory allocation error */ - { free(rank1); - return 0.0; - } - avgrank = 0.5*(m-1); /* Average rank */ - for (i = 0; i < m; i++) - { const double value1 = rank1[i]; - const double value2 = rank2[i]; - result += value1 * value2; - denom1 += value1 * value1; - denom2 += value2 * value2; - } - /* Note: denom1 and denom2 cannot be calculated directly from the number - * of elements. If two elements have the same rank, the squared sum of - * their ranks will change. - */ - free(rank1); - free(rank2); - result /= m; - denom1 /= m; - denom2 /= m; - result -= avgrank * avgrank; - denom1 -= avgrank * avgrank; - denom2 -= avgrank * avgrank; - if (denom1 <= 0) return 1; /* include '<' to deal with roundoff errors */ - if (denom2 <= 0) return 1; /* include '<' to deal with roundoff errors */ - result = result / sqrt(denom1*denom2); - result = 1. - result; - return result; -} - -/* ********************************************************************* */ - -static -double kendall (int n, double** data1, double** data2, int** mask1, int** mask2, - const double weight[], int index1, int index2, int transpose) -/* -Purpose -======= - -The kendall routine calculates the Kendall distance between two -rows or columns. The Kendall distance is defined as one minus Kendall's tau. - -Arguments -========= - -n (input) int -The number of elements in a row or column. If transpose==0, then n is the number -of columns; otherwise, n is the number of rows. - -data1 (input) double array -The data array containing the first vector. - -data2 (input) double array -The data array containing the second vector. - -mask1 (input) int array -This array which elements in data1 are missing. If mask1[i][j]==0, then -data1[i][j] is missing. - -mask2 (input) int array -This array which elements in data2 are missing. If mask2[i][j]==0, then -data2[i][j] is missing. - -weight (input) double[n] -These weights are ignored, but included for consistency with other distance -measures. - -index1 (input) int -Index of the first row or column. - -index2 (input) int -Index of the second row or column. - -transpose (input) int -If transpose==0, the distance between two rows in the matrix is calculated. -Otherwise, the distance between two columns in the matrix is calculated. -============================================================================ -*/ -{ int con = 0; - int dis = 0; - int exx = 0; - int exy = 0; - int flag = 0; - /* flag will remain zero if no nonzero combinations of mask1 and mask2 are - * found. - */ - double denomx; - double denomy; - double tau; - int i, j; - if (transpose==0) - { for (i = 0; i < n; i++) - { if (mask1[index1][i] && mask2[index2][i]) - { for (j = 0; j < i; j++) - { if (mask1[index1][j] && mask2[index2][j]) - { double x1 = data1[index1][i]; - double x2 = data1[index1][j]; - double y1 = data2[index2][i]; - double y2 = data2[index2][j]; - if (x1 < x2 && y1 < y2) con++; - if (x1 > x2 && y1 > y2) con++; - if (x1 < x2 && y1 > y2) dis++; - if (x1 > x2 && y1 < y2) dis++; - if (x1 == x2 && y1 != y2) exx++; - if (x1 != x2 && y1 == y2) exy++; - flag = 1; - } - } - } - } - } - else - { for (i = 0; i < n; i++) - { if (mask1[i][index1] && mask2[i][index2]) - { for (j = 0; j < i; j++) - { if (mask1[j][index1] && mask2[j][index2]) - { double x1 = data1[i][index1]; - double x2 = data1[j][index1]; - double y1 = data2[i][index2]; - double y2 = data2[j][index2]; - if (x1 < x2 && y1 < y2) con++; - if (x1 > x2 && y1 > y2) con++; - if (x1 < x2 && y1 > y2) dis++; - if (x1 > x2 && y1 < y2) dis++; - if (x1 == x2 && y1 != y2) exx++; - if (x1 != x2 && y1 == y2) exy++; - flag = 1; - } - } - } - } - } - if (!flag) return 0.; - denomx = con + dis + exx; - denomy = con + dis + exy; - if (denomx==0) return 1; - if (denomy==0) return 1; - tau = (con-dis)/sqrt(denomx*denomy); - return 1.-tau; -} - -/* ********************************************************************* */ - -static double(*setmetric(char dist)) - (int, double**, double**, int**, int**, const double[], int, int, int) -{ switch(dist) - { case 'e': return &euclid; - case 'b': return &cityblock; - case 'c': return &correlation; - case 'a': return &acorrelation; - case 'u': return &ucorrelation; - case 'x': return &uacorrelation; - case 's': return &spearman; - case 'k': return &kendall; - default: return &euclid; - } - return NULL; /* Never get here */ -} - -/* ********************************************************************* */ - -static double uniform(void) -/* -Purpose -======= - -This routine returns a uniform random number between 0.0 and 1.0. Both 0.0 -and 1.0 are excluded. This random number generator is described in: - -Pierre l'Ecuyer -Efficient and Portable Combined Random Number Generators -Communications of the ACM, Volume 31, Number 6, June 1988, pages 742-749,774. - -The first time this routine is called, it initializes the random number -generator using the current time. First, the current epoch time in seconds is -used as a seed for the random number generator in the C library. The first two -random numbers generated by this generator are used to initialize the random -number generator implemented in this routine. - - -Arguments -========= - -None. - - -Return value -============ - -A double-precison number between 0.0 and 1.0. -============================================================================ -*/ -{ int z; - static const int m1 = 2147483563; - static const int m2 = 2147483399; - const double scale = 1.0/m1; - - static int s1 = 0; - static int s2 = 0; - - if (s1==0 || s2==0) /* initialize */ - { unsigned int initseed = (unsigned int) time(0); - srand(initseed); - s1 = rand(); - s2 = rand(); - } - - do - { int k; - k = s1/53668; - s1 = 40014*(s1-k*53668)-k*12211; - if (s1 < 0) s1+=m1; - k = s2/52774; - s2 = 40692*(s2-k*52774)-k*3791; - if(s2 < 0) s2+=m2; - z = s1-s2; - if(z < 1) z+=(m1-1); - } while (z==m1); /* To avoid returning 1.0 */ - - return z*scale; -} - -/* ************************************************************************ */ - -static int binomial(int n, double p) -/* -Purpose -======= - -This routine generates a random number between 0 and n inclusive, following -the binomial distribution with probability p and n trials. The routine is -based on the BTPE algorithm, described in: - -Voratas Kachitvichyanukul and Bruce W. Schmeiser: -Binomial Random Variate Generation -Communications of the ACM, Volume 31, Number 2, February 1988, pages 216-222. - - -Arguments -========= - -p (input) double -The probability of a single event. This probability should be less than or -equal to 0.5. - -n (input) int -The number of trials. - - -Return value -============ - -An integer drawn from a binomial distribution with parameters (p, n). - -============================================================================ -*/ -{ const double q = 1 - p; - if (n*p < 30.0) /* Algorithm BINV */ - { const double s = p/q; - const double a = (n+1)*s; - double r = exp(n*log(q)); /* pow() causes a crash on AIX */ - int x = 0; - double u = uniform(); - while(1) - { if (u < r) return x; - u-=r; - x++; - r *= (a/x)-s; - } - } - else /* Algorithm BTPE */ - { /* Step 0 */ - const double fm = n*p + p; - const int m = (int) fm; - const double p1 = floor(2.195*sqrt(n*p*q) -4.6*q) + 0.5; - const double xm = m + 0.5; - const double xl = xm - p1; - const double xr = xm + p1; - const double c = 0.134 + 20.5/(15.3+m); - const double a = (fm-xl)/(fm-xl*p); - const double b = (xr-fm)/(xr*q); - const double lambdal = a*(1.0+0.5*a); - const double lambdar = b*(1.0+0.5*b); - const double p2 = p1*(1+2*c); - const double p3 = p2 + c/lambdal; - const double p4 = p3 + c/lambdar; - while (1) - { /* Step 1 */ - int y; - int k; - double u = uniform(); - double v = uniform(); - u *= p4; - if (u <= p1) return (int)(xm-p1*v+u); - /* Step 2 */ - if (u > p2) - { /* Step 3 */ - if (u > p3) - { /* Step 4 */ - y = (int)(xr-log(v)/lambdar); - if (y > n) continue; - /* Go to step 5 */ - v = v*(u-p3)*lambdar; - } - else - { y = (int)(xl+log(v)/lambdal); - if (y < 0) continue; - /* Go to step 5 */ - v = v*(u-p2)*lambdal; - } - } - else - { const double x = xl + (u-p1)/c; - v = v*c + 1.0 - fabs(m-x+0.5)/p1; - if (v > 1) continue; - /* Go to step 5 */ - y = (int)x; - } - /* Step 5 */ - /* Step 5.0 */ - k = abs(y-m); - if (k > 20 && k < 0.5*n*p*q-1.0) - { /* Step 5.2 */ - double rho = (k/(n*p*q))*((k*(k/3.0 + 0.625) + 0.1666666666666)/(n*p*q)+0.5); - double t = -k*k/(2*n*p*q); - double A = log(v); - if (A < t-rho) return y; - else if (A > t+rho) continue; - else - { /* Step 5.3 */ - double x1 = y+1; - double f1 = m+1; - double z = n+1-m; - double w = n-y+1; - double x2 = x1*x1; - double f2 = f1*f1; - double z2 = z*z; - double w2 = w*w; - if (A > xm * log(f1/x1) + (n-m+0.5)*log(z/w) - + (y-m)*log(w*p/(x1*q)) - + (13860.-(462.-(132.-(99.-140./f2)/f2)/f2)/f2)/f1/166320. - + (13860.-(462.-(132.-(99.-140./z2)/z2)/z2)/z2)/z/166320. - + (13860.-(462.-(132.-(99.-140./x2)/x2)/x2)/x2)/x1/166320. - + (13860.-(462.-(132.-(99.-140./w2)/w2)/w2)/w2)/w/166320.) - continue; - return y; - } - } - else - { /* Step 5.1 */ - int i; - const double s = p/q; - const double aa = s*(n+1); - double f = 1.0; - for (i = m; i < y; f *= (aa/(++i)-s)); - for (i = y; i < m; f /= (aa/(++i)-s)); - if (v > f) continue; - return y; - } - } - } - /* Never get here */ - return -1; -} - -/* ************************************************************************ */ - -static void randomassign (int nclusters, int nelements, int clusterid[]) -/* -Purpose -======= - -The randomassign routine performs an initial random clustering, needed for -k-means or k-median clustering. Elements (genes or microarrays) are randomly -assigned to clusters. The number of elements in each cluster is chosen -randomly, making sure that each cluster will receive at least one element. - - -Arguments -========= - -nclusters (input) int -The number of clusters. - -nelements (input) int -The number of elements to be clustered (i.e., the number of genes or microarrays -to be clustered). - -clusterid (output) int[nelements] -The cluster number to which an element was assigned. - -============================================================================ -*/ -{ int i, j; - int k = 0; - double p; - int n = nelements-nclusters; - /* Draw the number of elements in each cluster from a multinomial - * distribution, reserving ncluster elements to set independently - * in order to guarantee that none of the clusters are empty. - */ - for (i = 0; i < nclusters-1; i++) - { p = 1.0/(nclusters-i); - j = binomial(n, p); - n -= j; - j += k+1; /* Assign at least one element to cluster i */ - for ( ; k < j; k++) clusterid[k] = i; - } - /* Assign the remaining elements to the last cluster */ - for ( ; k < nelements; k++) clusterid[k] = i; - - /* Create a random permutation of the cluster assignments */ - for (i = 0; i < nelements; i++) - { j = (int) (i + (nelements-i)*uniform()); - k = clusterid[j]; - clusterid[j] = clusterid[i]; - clusterid[i] = k; - } - - return; -} - -/* ********************************************************************* */ - -static void getclustermeans(int nclusters, int nrows, int ncolumns, - double** data, int** mask, int clusterid[], double** cdata, int** cmask, - int transpose) -/* -Purpose -======= - -The getclustermeans routine calculates the cluster centroids, given to which -cluster each element belongs. The centroid is defined as the mean over all -elements for each dimension. - -Arguments -========= - -nclusters (input) int -The number of clusters. - -nrows (input) int -The number of rows in the gene expression data matrix, equal to the number of -genes. - -ncolumns (input) int -The number of columns in the gene expression data matrix, equal to the number of -microarrays. - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If mask[i][j]==0, then -data[i][j] is missing. - -clusterid (output) int[nrows] if transpose==0 - int[ncolumns] if transpose==1 -The cluster number to which each element belongs. If transpose==0, then the -dimension of clusterid is equal to nrows (the number of genes). Otherwise, it -is equal to ncolumns (the number of microarrays). - -cdata (output) double[nclusters][ncolumns] if transpose==0 - double[nrows][nclusters] if transpose==1 -On exit of getclustermeans, this array contains the cluster centroids. - -cmask (output) int[nclusters][ncolumns] if transpose==0 - int[nrows][nclusters] if transpose==1 -This array shows which data values of are missing for each centroid. If -cmask[i][j]==0, then cdata[i][j] is missing. A data value is missing for -a centroid if all corresponding data values of the cluster members are missing. - -transpose (input) int -If transpose==0, clusters of rows (genes) are specified. Otherwise, clusters of -columns (microarrays) are specified. - -======================================================================== -*/ -{ int i, j, k; - if (transpose==0) - { for (i = 0; i < nclusters; i++) - { for (j = 0; j < ncolumns; j++) - { cmask[i][j] = 0; - cdata[i][j] = 0.; - } - } - for (k = 0; k < nrows; k++) - { i = clusterid[k]; - for (j = 0; j < ncolumns; j++) - { if (mask[k][j] != 0) - { cdata[i][j]+=data[k][j]; - cmask[i][j]++; - } - } - } - for (i = 0; i < nclusters; i++) - { for (j = 0; j < ncolumns; j++) - { if (cmask[i][j]>0) - { cdata[i][j] /= cmask[i][j]; - cmask[i][j] = 1; - } - } - } - } - else - { for (i = 0; i < nrows; i++) - { for (j = 0; j < nclusters; j++) - { cdata[i][j] = 0.; - cmask[i][j] = 0; - } - } - for (k = 0; k < ncolumns; k++) - { i = clusterid[k]; - for (j = 0; j < nrows; j++) - { if (mask[j][k] != 0) - { cdata[j][i]+=data[j][k]; - cmask[j][i]++; - } - } - } - for (i = 0; i < nrows; i++) - { for (j = 0; j < nclusters; j++) - { if (cmask[i][j]>0) - { cdata[i][j] /= cmask[i][j]; - cmask[i][j] = 1; - } - } - } - } -} - -/* ********************************************************************* */ - -static void -getclustermedians(int nclusters, int nrows, int ncolumns, - double** data, int** mask, int clusterid[], double** cdata, int** cmask, - int transpose, double cache[]) -/* -Purpose -======= - -The getclustermedians routine calculates the cluster centroids, given to which -cluster each element belongs. The centroid is defined as the median over all -elements for each dimension. - -Arguments -========= - -nclusters (input) int -The number of clusters. - -nrows (input) int -The number of rows in the gene expression data matrix, equal to the number of -genes. - -ncolumns (input) int -The number of columns in the gene expression data matrix, equal to the number of -microarrays. - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If mask[i][j]==0, then -data[i][j] is missing. - -clusterid (output) int[nrows] if transpose==0 - int[ncolumns] if transpose==1 -The cluster number to which each element belongs. If transpose==0, then the -dimension of clusterid is equal to nrows (the number of genes). Otherwise, it -is equal to ncolumns (the number of microarrays). - -cdata (output) double[nclusters][ncolumns] if transpose==0 - double[nrows][nclusters] if transpose==1 -On exit of getclustermedians, this array contains the cluster centroids. - -cmask (output) int[nclusters][ncolumns] if transpose==0 - int[nrows][nclusters] if transpose==1 -This array shows which data values of are missing for each centroid. If -cmask[i][j]==0, then cdata[i][j] is missing. A data value is missing for -a centroid if all corresponding data values of the cluster members are missing. - -transpose (input) int -If transpose==0, clusters of rows (genes) are specified. Otherwise, clusters of -columns (microarrays) are specified. - -cache (input) double[nrows] if transpose==0 - double[ncolumns] if transpose==1 -This array should be allocated before calling getclustermedians; its contents -on input is not relevant. This array is used as a temporary storage space when -calculating the medians. - -======================================================================== -*/ -{ int i, j, k; - if (transpose==0) - { for (i = 0; i < nclusters; i++) - { for (j = 0; j < ncolumns; j++) - { int count = 0; - for (k = 0; k < nrows; k++) - { if (i==clusterid[k] && mask[k][j]) - { cache[count] = data[k][j]; - count++; - } - } - if (count>0) - { cdata[i][j] = median(count,cache); - cmask[i][j] = 1; - } - else - { cdata[i][j] = 0.; - cmask[i][j] = 0; - } - } - } - } - else - { for (i = 0; i < nclusters; i++) - { for (j = 0; j < nrows; j++) - { int count = 0; - for (k = 0; k < ncolumns; k++) - { if (i==clusterid[k] && mask[j][k]) - { cache[count] = data[j][k]; - count++; - } - } - if (count>0) - { cdata[j][i] = median(count,cache); - cmask[j][i] = 1; - } - else - { cdata[j][i] = 0.; - cmask[j][i] = 0; - } - } - } - } -} - -/* ********************************************************************* */ - -int getclustercentroids(int nclusters, int nrows, int ncolumns, - double** data, int** mask, int clusterid[], double** cdata, int** cmask, - int transpose, char method) -/* -Purpose -======= - -The getclustercentroids routine calculates the cluster centroids, given to -which cluster each element belongs. Depending on the argument method, the -centroid is defined as either the mean or the median for each dimension over -all elements belonging to a cluster. - -Arguments -========= - -nclusters (input) int -The number of clusters. - -nrows (input) int -The number of rows in the gene expression data matrix, equal to the number of -genes. - -ncolumns (input) int -The number of columns in the gene expression data matrix, equal to the number of -microarrays. - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If mask[i][j]==0, then -data[i][j] is missing. - -clusterid (output) int[nrows] if transpose==0 - int[ncolumns] if transpose==1 -The cluster number to which each element belongs. If transpose==0, then the -dimension of clusterid is equal to nrows (the number of genes). Otherwise, it -is equal to ncolumns (the number of microarrays). - -cdata (output) double[nclusters][ncolumns] if transpose==0 - double[nrows][nclusters] if transpose==1 -On exit of getclustercentroids, this array contains the cluster centroids. - -cmask (output) int[nclusters][ncolumns] if transpose==0 - int[nrows][nclusters] if transpose==1 -This array shows which data values of are missing for each centroid. If -cmask[i][j]==0, then cdata[i][j] is missing. A data value is missing for -a centroid if all corresponding data values of the cluster members are missing. - -transpose (input) int -If transpose==0, clusters of rows (genes) are specified. Otherwise, clusters of -columns (microarrays) are specified. - -method (input) char -For method=='a', the centroid is defined as the mean over all elements -belonging to a cluster for each dimension. -For method=='m', the centroid is defined as the median over all elements -belonging to a cluster for each dimension. - -Return value -============ - -The function returns an integer to indicate success or failure. If a -memory error occurs, or if method is not 'm' or 'a', getclustercentroids -returns 0. If successful, getclustercentroids returns 1. -======================================================================== -*/ -{ switch(method) - { case 'm': - { const int nelements = (transpose==0) ? nrows : ncolumns; - double* cache = malloc(nelements*sizeof(double)); - if (!cache) return 0; - getclustermedians(nclusters, nrows, ncolumns, data, mask, clusterid, - cdata, cmask, transpose, cache); - free(cache); - return 1; - } - case 'a': - { getclustermeans(nclusters, nrows, ncolumns, data, mask, clusterid, - cdata, cmask, transpose); - return 1; - } - } - return 0; -} - -/* ********************************************************************* */ - -void getclustermedoids(int nclusters, int nelements, double** distance, - int clusterid[], int centroids[], double errors[]) -/* -Purpose -======= - -The getclustermedoids routine calculates the cluster centroids, given to which -cluster each element belongs. The centroid is defined as the element with the -smallest sum of distances to the other elements. - -Arguments -========= - -nclusters (input) int -The number of clusters. - -nelements (input) int -The total number of elements. - -distmatrix (input) double array, ragged - (number of rows is nelements, number of columns is equal to the row number) -The distance matrix. To save space, the distance matrix is given in the -form of a ragged array. The distance matrix is symmetric and has zeros -on the diagonal. See distancematrix for a description of the content. - -clusterid (output) int[nelements] -The cluster number to which each element belongs. - -centroid (output) int[nclusters] -The index of the element that functions as the centroid for each cluster. - -errors (output) double[nclusters] -The within-cluster sum of distances between the items and the cluster -centroid. - -======================================================================== -*/ -{ int i, j, k; - for (j = 0; j < nclusters; j++) errors[j] = DBL_MAX; - for (i = 0; i < nelements; i++) - { double d = 0.0; - j = clusterid[i]; - for (k = 0; k < nelements; k++) - { if (i==k || clusterid[k]!=j) continue; - d += (i < k ? distance[k][i] : distance[i][k]); - if (d > errors[j]) break; - } - if (d < errors[j]) - { errors[j] = d; - centroids[j] = i; - } - } -} - -/* ********************************************************************* */ - -static int -kmeans(int nclusters, int nrows, int ncolumns, double** data, int** mask, - double weight[], int transpose, int npass, char dist, - double** cdata, int** cmask, int clusterid[], double* error, - int tclusterid[], int counts[], int mapping[]) -{ int i, j, k; - const int nelements = (transpose==0) ? nrows : ncolumns; - const int ndata = (transpose==0) ? ncolumns : nrows; - int ifound = 1; - int ipass = 0; - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - /* We save the clustering solution periodically and check if it reappears */ - int* saved = malloc(nelements*sizeof(int)); - if (saved==NULL) return -1; - - *error = DBL_MAX; - - do - { double total = DBL_MAX; - int counter = 0; - int period = 10; - - /* Perform the EM algorithm. First, randomly assign elements to clusters. */ - if (npass!=0) randomassign (nclusters, nelements, tclusterid); - - for (i = 0; i < nclusters; i++) counts[i] = 0; - for (i = 0; i < nelements; i++) counts[tclusterid[i]]++; - - /* Start the loop */ - while(1) - { double previous = total; - total = 0.0; - - if (counter % period == 0) /* Save the current cluster assignments */ - { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i]; - if (period < INT_MAX / 2) period *= 2; - } - counter++; - - /* Find the center */ - getclustermeans(nclusters, nrows, ncolumns, data, mask, tclusterid, - cdata, cmask, transpose); - - for (i = 0; i < nelements; i++) - /* Calculate the distances */ - { double distance; - k = tclusterid[i]; - if (counts[k]==1) continue; - /* No reassignment if that would lead to an empty cluster */ - /* Treat the present cluster as a special case */ - distance = metric(ndata,data,cdata,mask,cmask,weight,i,k,transpose); - for (j = 0; j < nclusters; j++) - { double tdistance; - if (j==k) continue; - tdistance = metric(ndata,data,cdata,mask,cmask,weight,i,j,transpose); - if (tdistance < distance) - { distance = tdistance; - counts[tclusterid[i]]--; - tclusterid[i] = j; - counts[j]++; - } - } - total += distance; - } - if (total>=previous) break; - /* total>=previous is FALSE on some machines even if total and previous - * are bitwise identical. */ - for (i = 0; i < nelements; i++) - if (saved[i]!=tclusterid[i]) break; - if (i==nelements) - break; /* Identical solution found; break out of this loop */ - } - - if (npass<=1) - { *error = total; - break; - } - - for (i = 0; i < nclusters; i++) mapping[i] = -1; - for (i = 0; i < nelements; i++) - { j = tclusterid[i]; - k = clusterid[i]; - if (mapping[k] == -1) mapping[k] = j; - else if (mapping[k] != j) - { if (total < *error) - { ifound = 1; - *error = total; - for (j = 0; j < nelements; j++) clusterid[j] = tclusterid[j]; - } - break; - } - } - if (i==nelements) ifound++; /* break statement not encountered */ - } while (++ipass < npass); - - free(saved); - return ifound; -} - -/* ---------------------------------------------------------------------- */ - -static int -kmedians(int nclusters, int nrows, int ncolumns, double** data, int** mask, - double weight[], int transpose, int npass, char dist, - double** cdata, int** cmask, int clusterid[], double* error, - int tclusterid[], int counts[], int mapping[], double cache[]) -{ int i, j, k; - const int nelements = (transpose==0) ? nrows : ncolumns; - const int ndata = (transpose==0) ? ncolumns : nrows; - int ifound = 1; - int ipass = 0; - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - /* We save the clustering solution periodically and check if it reappears */ - int* saved = malloc(nelements*sizeof(int)); - if (saved==NULL) return -1; - - *error = DBL_MAX; - - do - { double total = DBL_MAX; - int counter = 0; - int period = 10; - - /* Perform the EM algorithm. First, randomly assign elements to clusters. */ - if (npass!=0) randomassign (nclusters, nelements, tclusterid); - - for (i = 0; i < nclusters; i++) counts[i]=0; - for (i = 0; i < nelements; i++) counts[tclusterid[i]]++; - - /* Start the loop */ - while(1) - { double previous = total; - total = 0.0; - - if (counter % period == 0) /* Save the current cluster assignments */ - { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i]; - if (period < INT_MAX / 2) period *= 2; - } - counter++; - - /* Find the center */ - getclustermedians(nclusters, nrows, ncolumns, data, mask, tclusterid, - cdata, cmask, transpose, cache); - - for (i = 0; i < nelements; i++) - /* Calculate the distances */ - { double distance; - k = tclusterid[i]; - if (counts[k]==1) continue; - /* No reassignment if that would lead to an empty cluster */ - /* Treat the present cluster as a special case */ - distance = metric(ndata,data,cdata,mask,cmask,weight,i,k,transpose); - for (j = 0; j < nclusters; j++) - { double tdistance; - if (j==k) continue; - tdistance = metric(ndata,data,cdata,mask,cmask,weight,i,j,transpose); - if (tdistance < distance) - { distance = tdistance; - counts[tclusterid[i]]--; - tclusterid[i] = j; - counts[j]++; - } - } - total += distance; - } - if (total>=previous) break; - /* total>=previous is FALSE on some machines even if total and previous - * are bitwise identical. */ - for (i = 0; i < nelements; i++) - if (saved[i]!=tclusterid[i]) break; - if (i==nelements) - break; /* Identical solution found; break out of this loop */ - } - - if (npass<=1) - { *error = total; - break; - } - - for (i = 0; i < nclusters; i++) mapping[i] = -1; - for (i = 0; i < nelements; i++) - { j = tclusterid[i]; - k = clusterid[i]; - if (mapping[k] == -1) mapping[k] = j; - else if (mapping[k] != j) - { if (total < *error) - { ifound = 1; - *error = total; - for (j = 0; j < nelements; j++) clusterid[j] = tclusterid[j]; - } - break; - } - } - if (i==nelements) ifound++; /* break statement not encountered */ - } while (++ipass < npass); - - free(saved); - return ifound; -} - -/* ********************************************************************* */ - -void kcluster (int nclusters, int nrows, int ncolumns, - double** data, int** mask, double weight[], int transpose, - int npass, char method, char dist, - int clusterid[], double* error, int* ifound) -/* -Purpose -======= - -The kcluster routine performs k-means or k-median clustering on a given set of -elements, using the specified distance measure. The number of clusters is given -by the user. Multiple passes are being made to find the optimal clustering -solution, each time starting from a different initial clustering. - - -Arguments -========= - -nclusters (input) int -The number of clusters to be found. - -data (input) double[nrows][ncolumns] -The array containing the data of the elements to be clustered (i.e., the gene -expression data). - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If -mask[i][j] == 0, then data[i][j] is missing. - -nrows (input) int -The number of rows in the data matrix, equal to the number of genes. - -ncolumns (input) int -The number of columns in the data matrix, equal to the number of microarrays. - -weight (input) double[n] -The weights that are used to calculate the distance. - -transpose (input) int -If transpose==0, the rows of the matrix are clustered. Otherwise, columns -of the matrix are clustered. - -npass (input) int -The number of times clustering is performed. Clustering is performed npass -times, each time starting from a different (random) initial assignment of -genes to clusters. The clustering solution with the lowest within-cluster sum -of distances is chosen. -If npass==0, then the clustering algorithm will be run once, where the initial -assignment of elements to clusters is taken from the clusterid array. - -method (input) char -Defines whether the arithmetic mean (method=='a') or the median -(method=='m') is used to calculate the cluster center. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -clusterid (output; input) int[nrows] if transpose==0 - int[ncolumns] if transpose==1 -The cluster number to which a gene or microarray was assigned. If npass==0, -then on input clusterid contains the initial clustering assignment from which -the clustering algorithm starts. On output, it contains the clustering solution -that was found. - -error (output) double* -The sum of distances to the cluster center of each item in the optimal k-means -clustering solution that was found. - -ifound (output) int* -The number of times the optimal clustering solution was -found. The value of ifound is at least 1; its maximum value is npass. If the -number of clusters is larger than the number of elements being clustered, -*ifound is set to 0 as an error code. If a memory allocation error occurs, -*ifound is set to -1. - -======================================================================== -*/ -{ const int nelements = (transpose==0) ? nrows : ncolumns; - const int ndata = (transpose==0) ? ncolumns : nrows; - - int i; - int ok; - int* tclusterid; - int* mapping = NULL; - double** cdata; - int** cmask; - int* counts; - - if (nelements < nclusters) - { *ifound = 0; - return; - } - /* More clusters asked for than elements available */ - - *ifound = -1; - - /* This will contain the number of elements in each cluster, which is - * needed to check for empty clusters. */ - counts = malloc(nclusters*sizeof(int)); - if(!counts) return; - - /* Find out if the user specified an initial clustering */ - if (npass<=1) tclusterid = clusterid; - else - { tclusterid = malloc(nelements*sizeof(int)); - if (!tclusterid) - { free(counts); - return; - } - mapping = malloc(nclusters*sizeof(int)); - if (!mapping) - { free(counts); - free(tclusterid); - return; - } - for (i = 0; i < nelements; i++) clusterid[i] = 0; - } - - /* Allocate space to store the centroid data */ - if (transpose==0) ok = makedatamask(nclusters, ndata, &cdata, &cmask); - else ok = makedatamask(ndata, nclusters, &cdata, &cmask); - if(!ok) - { free(counts); - if(npass>1) - { free(tclusterid); - free(mapping); - return; - } - } - - if (method=='m') - { double* cache = malloc(nelements*sizeof(double)); - if(cache) - { *ifound = kmedians(nclusters, nrows, ncolumns, data, mask, weight, - transpose, npass, dist, cdata, cmask, clusterid, error, - tclusterid, counts, mapping, cache); - free(cache); - } - } - else - *ifound = kmeans(nclusters, nrows, ncolumns, data, mask, weight, - transpose, npass, dist, cdata, cmask, clusterid, error, - tclusterid, counts, mapping); - - /* Deallocate temporarily used space */ - if (npass > 1) - { free(mapping); - free(tclusterid); - } - - if (transpose==0) freedatamask(nclusters, cdata, cmask); - else freedatamask(ndata, cdata, cmask); - - free(counts); -} - -/* *********************************************************************** */ - -void kmedoids (int nclusters, int nelements, double** distmatrix, - int npass, int clusterid[], double* error, int* ifound) -/* -Purpose -======= - -The kmedoids routine performs k-medoids clustering on a given set of elements, -using the distance matrix and the number of clusters passed by the user. -Multiple passes are being made to find the optimal clustering solution, each -time starting from a different initial clustering. - - -Arguments -========= - -nclusters (input) int -The number of clusters to be found. - -nelements (input) int -The number of elements to be clustered. - -distmatrix (input) double array, ragged - (number of rows is nelements, number of columns is equal to the row number) -The distance matrix. To save space, the distance matrix is given in the -form of a ragged array. The distance matrix is symmetric and has zeros -on the diagonal. See distancematrix for a description of the content. - -npass (input) int -The number of times clustering is performed. Clustering is performed npass -times, each time starting from a different (random) initial assignment of genes -to clusters. The clustering solution with the lowest within-cluster sum of -distances is chosen. -If npass==0, then the clustering algorithm will be run once, where the initial -assignment of elements to clusters is taken from the clusterid array. - -clusterid (output; input) int[nelements] -On input, if npass==0, then clusterid contains the initial clustering assignment -from which the clustering algorithm starts; all numbers in clusterid should be -between zero and nelements-1 inclusive. If npass!=0, clusterid is ignored on -input. -On output, clusterid contains the clustering solution that was found: clusterid -contains the number of the cluster to which each item was assigned. On output, -the number of a cluster is defined as the item number of the centroid of the -cluster. - -error (output) double -The sum of distances to the cluster center of each item in the optimal k-medoids -clustering solution that was found. - -ifound (output) int -If kmedoids is successful: the number of times the optimal clustering solution -was found. The value of ifound is at least 1; its maximum value is npass. -If the user requested more clusters than elements available, ifound is set -to 0. If kmedoids fails due to a memory allocation error, ifound is set to -1. - -======================================================================== -*/ -{ int i, j, icluster; - int* tclusterid; - int* saved; - int* centroids; - double* errors; - int ipass = 0; - - if (nelements < nclusters) - { *ifound = 0; - return; - } /* More clusters asked for than elements available */ - - *ifound = -1; - - /* We save the clustering solution periodically and check if it reappears */ - saved = malloc(nelements*sizeof(int)); - if (saved==NULL) return; - - centroids = malloc(nclusters*sizeof(int)); - if(!centroids) - { free(saved); - return; - } - - errors = malloc(nclusters*sizeof(double)); - if(!errors) - { free(saved); - free(centroids); - return; - } - - /* Find out if the user specified an initial clustering */ - if (npass<=1) tclusterid = clusterid; - else - { tclusterid = malloc(nelements*sizeof(int)); - if(!tclusterid) - { free(saved); - free(centroids); - free(errors); - return; - } - } - - *error = DBL_MAX; - do /* Start the loop */ - { double total = DBL_MAX; - int counter = 0; - int period = 10; - - if (npass!=0) randomassign (nclusters, nelements, tclusterid); - while(1) - { double previous = total; - total = 0.0; - - if (counter % period == 0) /* Save the current cluster assignments */ - { for (i = 0; i < nelements; i++) saved[i] = tclusterid[i]; - if (period < INT_MAX / 2) period *= 2; - } - counter++; - - /* Find the center */ - getclustermedoids(nclusters, nelements, distmatrix, tclusterid, - centroids, errors); - - for (i = 0; i < nelements; i++) - /* Find the closest cluster */ - { double distance = DBL_MAX; - for (icluster = 0; icluster < nclusters; icluster++) - { double tdistance; - j = centroids[icluster]; - if (i==j) - { distance = 0.0; - tclusterid[i] = icluster; - break; - } - tdistance = (i > j) ? distmatrix[i][j] : distmatrix[j][i]; - if (tdistance < distance) - { distance = tdistance; - tclusterid[i] = icluster; - } - } - total += distance; - } - if (total>=previous) break; - /* total>=previous is FALSE on some machines even if total and previous - * are bitwise identical. */ - for (i = 0; i < nelements; i++) - if (saved[i]!=tclusterid[i]) break; - if (i==nelements) - break; /* Identical solution found; break out of this loop */ - } - - for (i = 0; i < nelements; i++) - { if (clusterid[i]!=centroids[tclusterid[i]]) - { if (total < *error) - { *ifound = 1; - *error = total; - /* Replace by the centroid in each cluster. */ - for (j = 0; j < nelements; j++) - clusterid[j] = centroids[tclusterid[j]]; - } - break; - } - } - if (i==nelements) (*ifound)++; /* break statement not encountered */ - } while (++ipass < npass); - - /* Deallocate temporarily used space */ - if (npass > 1) free(tclusterid); - - free(saved); - free(centroids); - free(errors); - - return; -} - -/* ******************************************************************** */ - -double** distancematrix (int nrows, int ncolumns, double** data, - int** mask, double weights[], char dist, int transpose) -/* -Purpose -======= - -The distancematrix routine calculates the distance matrix between genes or -microarrays using their measured gene expression data. Several distance measures -can be used. The routine returns a pointer to a ragged array containing the -distances between the genes. As the distance matrix is symmetric, with zeros on -the diagonal, only the lower triangular half of the distance matrix is saved. -The distancematrix routine allocates space for the distance matrix. If the -parameter transpose is set to a nonzero value, the distances between the columns -(microarrays) are calculated, otherwise distances between the rows (genes) are -calculated. -If sufficient space in memory cannot be allocated to store the distance matrix, -the routine returns a NULL pointer, and all memory allocated so far for the -distance matrix is freed. - - -Arguments -========= - -nrows (input) int -The number of rows in the gene expression data matrix (i.e., the number of -genes) - -ncolumns (input) int -The number of columns in the gene expression data matrix (i.e., the number of -microarrays) - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If mask[i][j]==0, then -data[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. The length of this vector -is equal to the number of columns if the distances between genes are calculated, -or the number of rows if the distances between microarrays are calculated. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -transpose (input) int -If transpose is equal to zero, the distances between the rows is -calculated. Otherwise, the distances between the columns is calculated. -The former is needed when genes are being clustered; the latter is used -when microarrays are being clustered. - -======================================================================== -*/ -{ /* First determine the size of the distance matrix */ - const int n = (transpose==0) ? nrows : ncolumns; - const int ndata = (transpose==0) ? ncolumns : nrows; - int i,j; - double** matrix; - - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - if (n < 2) return NULL; - - /* Set up the ragged array */ - matrix = malloc(n*sizeof(double*)); - if(matrix==NULL) return NULL; /* Not enough memory available */ - matrix[0] = NULL; - /* The zeroth row has zero columns. We allocate it anyway for convenience.*/ - for (i = 1; i < n; i++) - { matrix[i] = malloc(i*sizeof(double)); - if (matrix[i]==NULL) break; /* Not enough memory available */ - } - if (i < n) /* break condition encountered */ - { j = i; - for (i = 1; i < j; i++) free(matrix[i]); - return NULL; - } - - /* Calculate the distances and save them in the ragged array */ - for (i = 1; i < n; i++) - for (j = 0; j < i; j++) - matrix[i][j]=metric(ndata,data,data,mask,mask,weights,i,j,transpose); - - return matrix; -} - -/* ******************************************************************** */ - -double* calculate_weights(int nrows, int ncolumns, double** data, int** mask, - double weights[], int transpose, char dist, double cutoff, double exponent) - -/* -Purpose -======= - -This function calculates the weights using the weighting scheme proposed by -Michael Eisen: -w[i] = 1.0 / sum_{j where d[i][j]= n; i--) - { k = tree[i].left; - if (k>=0) - { clusterid[k] = icluster; - icluster++; - } - k = tree[i].right; - if (k>=0) - { clusterid[k] = icluster; - icluster++; - } - } - nodeid = malloc(n*sizeof(int)); - if(!nodeid) - { for (i = 0; i < nelements; i++) clusterid[i] = -1; - return; - } - for (i = 0; i < n; i++) nodeid[i] = -1; - for (i = n-1; i >= 0; i--) - { if(nodeid[i]<0) - { j = icluster; - nodeid[i] = j; - icluster++; - } - else j = nodeid[i]; - k = tree[i].left; - if (k<0) nodeid[-k-1] = j; else clusterid[k] = j; - k = tree[i].right; - if (k<0) nodeid[-k-1] = j; else clusterid[k] = j; - } - free(nodeid); - return; -} - -/* ******************************************************************** */ - -static -Node* pclcluster (int nrows, int ncolumns, double** data, int** mask, - double weight[], double** distmatrix, char dist, int transpose) - -/* - -Purpose -======= - -The pclcluster routine performs clustering using pairwise centroid-linking -on a given set of gene expression data, using the distance metric given by dist. - -Arguments -========= - -nrows (input) int -The number of rows in the gene expression data matrix, equal to the number of -genes. - -ncolumns (input) int -The number of columns in the gene expression data matrix, equal to the number of -microarrays. - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If -mask[i][j] == 0, then data[i][j] is missing. - -weight (input) double[ncolumns] if transpose==0; - double[nrows] if transpose==1 -The weights that are used to calculate the distance. The length of this vector -is ncolumns if genes are being clustered, and nrows if microarrays are being -clustered. - -transpose (input) int -If transpose==0, the rows of the matrix are clustered. Otherwise, columns -of the matrix are clustered. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -distmatrix (input) double** -The distance matrix. This matrix is precalculated by the calling routine -treecluster. The pclcluster routine modifies the contents of distmatrix, but -does not deallocate it. - -Return value -============ - -A pointer to a newly allocated array of Node structs, describing the -hierarchical clustering solution consisting of nelements-1 nodes. Depending on -whether genes (rows) or microarrays (columns) were clustered, nelements is -equal to nrows or ncolumns. See src/cluster.h for a description of the Node -structure. -If a memory error occurs, pclcluster returns NULL. -======================================================================== -*/ -{ int i, j; - const int nelements = (transpose==0) ? nrows : ncolumns; - int inode; - const int ndata = transpose ? nrows : ncolumns; - const int nnodes = nelements - 1; - - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - Node* result; - double** newdata; - int** newmask; - int* distid = malloc(nelements*sizeof(int)); - if(!distid) return NULL; - result = malloc(nnodes*sizeof(Node)); - if(!result) - { free(distid); - return NULL; - } - if(!makedatamask(nelements, ndata, &newdata, &newmask)) - { free(result); - free(distid); - return NULL; - } - - for (i = 0; i < nelements; i++) distid[i] = i; - /* To remember which row/column in the distance matrix contains what */ - - /* Storage for node data */ - if (transpose) - { for (i = 0; i < nelements; i++) - { for (j = 0; j < ndata; j++) - { newdata[i][j] = data[j][i]; - newmask[i][j] = mask[j][i]; - } - } - data = newdata; - mask = newmask; - } - else - { for (i = 0; i < nelements; i++) - { memcpy(newdata[i], data[i], ndata*sizeof(double)); - memcpy(newmask[i], mask[i], ndata*sizeof(int)); - } - data = newdata; - mask = newmask; - } - - for (inode = 0; inode < nnodes; inode++) - { /* Find the pair with the shortest distance */ - int is = 1; - int js = 0; - result[inode].distance = find_closest_pair(nelements-inode, distmatrix, &is, &js); - result[inode].left = distid[js]; - result[inode].right = distid[is]; - - /* Make node js the new node */ - for (i = 0; i < ndata; i++) - { data[js][i] = data[js][i]*mask[js][i] + data[is][i]*mask[is][i]; - mask[js][i] += mask[is][i]; - if (mask[js][i]) data[js][i] /= mask[js][i]; - } - free(data[is]); - free(mask[is]); - data[is] = data[nnodes-inode]; - mask[is] = mask[nnodes-inode]; - - /* Fix the distances */ - distid[is] = distid[nnodes-inode]; - for (i = 0; i < is; i++) - distmatrix[is][i] = distmatrix[nnodes-inode][i]; - for (i = is + 1; i < nnodes-inode; i++) - distmatrix[i][is] = distmatrix[nnodes-inode][i]; - - distid[js] = -inode-1; - for (i = 0; i < js; i++) - distmatrix[js][i] = metric(ndata,data,data,mask,mask,weight,js,i,0); - for (i = js + 1; i < nnodes-inode; i++) - distmatrix[i][js] = metric(ndata,data,data,mask,mask,weight,js,i,0); - } - - /* Free temporarily allocated space */ - free(data[0]); - free(mask[0]); - free(data); - free(mask); - free(distid); - - return result; -} - -/* ******************************************************************** */ - -static -int nodecompare(const void* a, const void* b) -/* Helper function for qsort. */ -{ const Node* node1 = (const Node*)a; - const Node* node2 = (const Node*)b; - const double term1 = node1->distance; - const double term2 = node2->distance; - if (term1 < term2) return -1; - if (term1 > term2) return +1; - return 0; -} - -/* ---------------------------------------------------------------------- */ - -static -Node* pslcluster (int nrows, int ncolumns, double** data, int** mask, - double weight[], double** distmatrix, char dist, int transpose) - -/* - -Purpose -======= - -The pslcluster routine performs single-linkage hierarchical clustering, using -either the distance matrix directly, if available, or by calculating the -distances from the data array. This implementation is based on the SLINK -algorithm, described in: -Sibson, R. (1973). SLINK: An optimally efficient algorithm for the single-link -cluster method. The Computer Journal, 16(1): 30-34. -The output of this algorithm is identical to conventional single-linkage -hierarchical clustering, but is much more memory-efficient and faster. Hence, -it can be applied to large data sets, for which the conventional single- -linkage algorithm fails due to lack of memory. - - -Arguments -========= - -nrows (input) int -The number of rows in the gene expression data matrix, equal to the number of -genes. - -ncolumns (input) int -The number of columns in the gene expression data matrix, equal to the number of -microarrays. - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If -mask[i][j] == 0, then data[i][j] is missing. - -weight (input) double[n] -The weights that are used to calculate the distance. The length of this vector -is ncolumns if genes are being clustered, and nrows if microarrays are being -clustered. - -transpose (input) int -If transpose==0, the rows of the matrix are clustered. Otherwise, columns -of the matrix are clustered. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -distmatrix (input) double** -The distance matrix. If the distance matrix is passed by the calling routine -treecluster, it is used by pslcluster to speed up the clustering calculation. -The pslcluster routine does not modify the contents of distmatrix, and does -not deallocate it. If distmatrix is NULL, the pairwise distances are calculated -by the pslcluster routine from the gene expression data (the data and mask -arrays) and stored in temporary arrays. If distmatrix is passed, the original -gene expression data (specified by the data and mask arguments) are not needed -and are therefore ignored. - - -Return value -============ - -A pointer to a newly allocated array of Node structs, describing the -hierarchical clustering solution consisting of nelements-1 nodes. Depending on -whether genes (rows) or microarrays (columns) were clustered, nelements is -equal to nrows or ncolumns. See src/cluster.h for a description of the Node -structure. -If a memory error occurs, pslcluster returns NULL. - -======================================================================== -*/ -{ int i, j, k; - const int nelements = transpose ? ncolumns : nrows; - const int nnodes = nelements - 1; - int* vector; - double* temp; - int* index; - Node* result; - temp = malloc(nnodes*sizeof(double)); - if(!temp) return NULL; - index = malloc(nelements*sizeof(int)); - if(!index) - { free(temp); - return NULL; - } - vector = malloc(nnodes*sizeof(int)); - if(!vector) - { free(index); - free(temp); - return NULL; - } - result = malloc(nelements*sizeof(Node)); - if(!result) - { free(vector); - free(index); - free(temp); - return NULL; - } - - for (i = 0; i < nnodes; i++) vector[i] = i; - - if(distmatrix) - { for (i = 0; i < nrows; i++) - { result[i].distance = DBL_MAX; - for (j = 0; j < i; j++) temp[j] = distmatrix[i][j]; - for (j = 0; j < i; j++) - { k = vector[j]; - if (result[j].distance >= temp[j]) - { if (result[j].distance < temp[k]) temp[k] = result[j].distance; - result[j].distance = temp[j]; - vector[j] = i; - } - else if (temp[j] < temp[k]) temp[k] = temp[j]; - } - for (j = 0; j < i; j++) - { - if (result[j].distance >= result[vector[j]].distance) vector[j] = i; - } - } - } - else - { const int ndata = transpose ? nrows : ncolumns; - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - for (i = 0; i < nelements; i++) - { result[i].distance = DBL_MAX; - for (j = 0; j < i; j++) temp[j] = - metric(ndata, data, data, mask, mask, weight, i, j, transpose); - for (j = 0; j < i; j++) - { k = vector[j]; - if (result[j].distance >= temp[j]) - { if (result[j].distance < temp[k]) temp[k] = result[j].distance; - result[j].distance = temp[j]; - vector[j] = i; - } - else if (temp[j] < temp[k]) temp[k] = temp[j]; - } - for (j = 0; j < i; j++) - if (result[j].distance >= result[vector[j]].distance) vector[j] = i; - } - } - free(temp); - - for (i = 0; i < nnodes; i++) result[i].left = i; - qsort(result, nnodes, sizeof(Node), nodecompare); - - for (i = 0; i < nelements; i++) index[i] = i; - for (i = 0; i < nnodes; i++) - { j = result[i].left; - k = vector[j]; - result[i].left = index[j]; - result[i].right = index[k]; - index[k] = -i-1; - } - free(vector); - free(index); - - result = realloc(result, nnodes*sizeof(Node)); - - return result; -} -/* ******************************************************************** */ - -static Node* pmlcluster (int nelements, double** distmatrix) -/* - -Purpose -======= - -The pmlcluster routine performs clustering using pairwise maximum- (complete-) -linking on the given distance matrix. - -Arguments -========= - -nelements (input) int -The number of elements to be clustered. - -distmatrix (input) double** -The distance matrix, with nelements rows, each row being filled up to the -diagonal. The elements on the diagonal are not used, as they are assumed to be -zero. The distance matrix will be modified by this routine. - -Return value -============ - -A pointer to a newly allocated array of Node structs, describing the -hierarchical clustering solution consisting of nelements-1 nodes. Depending on -whether genes (rows) or microarrays (columns) were clustered, nelements is -equal to nrows or ncolumns. See src/cluster.h for a description of the Node -structure. -If a memory error occurs, pmlcluster returns NULL. -======================================================================== -*/ -{ int j; - int n; - int* clusterid; - Node* result; - - clusterid = malloc(nelements*sizeof(int)); - if(!clusterid) return NULL; - result = malloc((nelements-1)*sizeof(Node)); - if (!result) - { free(clusterid); - return NULL; - } - - /* Setup a list specifying to which cluster a gene belongs */ - for (j = 0; j < nelements; j++) clusterid[j] = j; - - for (n = nelements; n > 1; n--) - { int is = 1; - int js = 0; - result[nelements-n].distance = find_closest_pair(n, distmatrix, &is, &js); - - /* Fix the distances */ - for (j = 0; j < js; j++) - distmatrix[js][j] = ccl_max(distmatrix[is][j],distmatrix[js][j]); - for (j = js+1; j < is; j++) - distmatrix[j][js] = ccl_max(distmatrix[is][j],distmatrix[j][js]); - for (j = is+1; j < n; j++) - distmatrix[j][js] = ccl_max(distmatrix[j][is],distmatrix[j][js]); - - for (j = 0; j < is; j++) distmatrix[is][j] = distmatrix[n-1][j]; - for (j = is+1; j < n-1; j++) distmatrix[j][is] = distmatrix[n-1][j]; - - /* Update clusterids */ - result[nelements-n].left = clusterid[is]; - result[nelements-n].right = clusterid[js]; - clusterid[js] = n-nelements-1; - clusterid[is] = clusterid[n-1]; - } - free(clusterid); - - return result; -} - -/* ******************************************************************* */ - -static Node* palcluster (int nelements, double** distmatrix) -/* -Purpose -======= - -The palcluster routine performs clustering using pairwise average -linking on the given distance matrix. - -Arguments -========= - -nelements (input) int -The number of elements to be clustered. - -distmatrix (input) double** -The distance matrix, with nelements rows, each row being filled up to the -diagonal. The elements on the diagonal are not used, as they are assumed to be -zero. The distance matrix will be modified by this routine. - -Return value -============ - -A pointer to a newly allocated array of Node structs, describing the -hierarchical clustering solution consisting of nelements-1 nodes. Depending on -whether genes (rows) or microarrays (columns) were clustered, nelements is -equal to nrows or ncolumns. See src/cluster.h for a description of the Node -structure. -If a memory error occurs, palcluster returns NULL. -======================================================================== -*/ -{ int j; - int n; - int* clusterid; - int* number; - Node* result; - - clusterid = malloc(nelements*sizeof(int)); - if(!clusterid) return NULL; - number = malloc(nelements*sizeof(int)); - if(!number) - { free(clusterid); - return NULL; - } - result = malloc((nelements-1)*sizeof(Node)); - if (!result) - { free(clusterid); - free(number); - return NULL; - } - - /* Setup a list specifying to which cluster a gene belongs, and keep track - * of the number of elements in each cluster (needed to calculate the - * average). */ - for (j = 0; j < nelements; j++) - { number[j] = 1; - clusterid[j] = j; - } - - for (n = nelements; n > 1; n--) - { int sum; - int is = 1; - int js = 0; - result[nelements-n].distance = find_closest_pair(n, distmatrix, &is, &js); - - /* Save result */ - result[nelements-n].left = clusterid[is]; - result[nelements-n].right = clusterid[js]; - - /* Fix the distances */ - sum = number[is] + number[js]; - for (j = 0; j < js; j++) - { distmatrix[js][j] = distmatrix[is][j]*number[is] - + distmatrix[js][j]*number[js]; - distmatrix[js][j] /= sum; - } - for (j = js+1; j < is; j++) - { distmatrix[j][js] = distmatrix[is][j]*number[is] - + distmatrix[j][js]*number[js]; - distmatrix[j][js] /= sum; - } - for (j = is+1; j < n; j++) - { distmatrix[j][js] = distmatrix[j][is]*number[is] - + distmatrix[j][js]*number[js]; - distmatrix[j][js] /= sum; - } - - for (j = 0; j < is; j++) distmatrix[is][j] = distmatrix[n-1][j]; - for (j = is+1; j < n-1; j++) distmatrix[j][is] = distmatrix[n-1][j]; - - /* Update number of elements in the clusters */ - number[js] = sum; - number[is] = number[n-1]; - - /* Update clusterids */ - clusterid[js] = n-nelements-1; - clusterid[is] = clusterid[n-1]; - } - free(clusterid); - free(number); - - return result; -} - -/* ******************************************************************* */ - -Node* treecluster (int nrows, int ncolumns, double** data, int** mask, - double weight[], int transpose, char dist, char method, double** distmatrix) -/* -Purpose -======= - -The treecluster routine performs hierarchical clustering using pairwise -single-, maximum-, centroid-, or average-linkage, as defined by method, on a -given set of gene expression data, using the distance metric given by dist. -If successful, the function returns a pointer to a newly allocated Tree struct -containing the hierarchical clustering solution, and NULL if a memory error -occurs. The pointer should be freed by the calling routine to prevent memory -leaks. - -Arguments -========= - -nrows (input) int -The number of rows in the data matrix, equal to the number of genes. - -ncolumns (input) int -The number of columns in the data matrix, equal to the number of microarrays. - -data (input) double[nrows][ncolumns] -The array containing the data of the vectors to be clustered. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If mask[i][j]==0, then -data[i][j] is missing. - -weight (input) double array[n] -The weights that are used to calculate the distance. - -transpose (input) int -If transpose==0, the rows of the matrix are clustered. Otherwise, columns -of the matrix are clustered. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -method (input) char -Defines which hierarchical clustering method is used: -method=='s': pairwise single-linkage clustering -method=='m': pairwise maximum- (or complete-) linkage clustering -method=='a': pairwise average-linkage clustering -method=='c': pairwise centroid-linkage clustering -For the first three, either the distance matrix or the gene expression data is -sufficient to perform the clustering algorithm. For pairwise centroid-linkage -clustering, however, the gene expression data are always needed, even if the -distance matrix itself is available. - -distmatrix (input) double** -The distance matrix. If the distance matrix is zero initially, the distance -matrix will be allocated and calculated from the data by treecluster, and -deallocated before treecluster returns. If the distance matrix is passed by the -calling routine, treecluster will modify the contents of the distance matrix as -part of the clustering algorithm, but will not deallocate it. The calling -routine should deallocate the distance matrix after the return from treecluster. - -Return value -============ - -A pointer to a newly allocated array of Node structs, describing the -hierarchical clustering solution consisting of nelements-1 nodes. Depending on -whether genes (rows) or microarrays (columns) were clustered, nelements is -equal to nrows or ncolumns. See src/cluster.h for a description of the Node -structure. -If a memory error occurs, treecluster returns NULL. - -======================================================================== -*/ -{ Node* result = NULL; - const int nelements = (transpose==0) ? nrows : ncolumns; - const int ldistmatrix = (distmatrix==NULL && method!='s') ? 1 : 0; - - if (nelements < 2) return NULL; - - /* Calculate the distance matrix if the user didn't give it */ - if(ldistmatrix) - { distmatrix = - distancematrix(nrows, ncolumns, data, mask, weight, dist, transpose); - if (!distmatrix) return NULL; /* Insufficient memory */ - } - - switch(method) - { case 's': - result = pslcluster(nrows, ncolumns, data, mask, weight, distmatrix, - dist, transpose); - break; - case 'm': - result = pmlcluster(nelements, distmatrix); - break; - case 'a': - result = palcluster(nelements, distmatrix); - break; - case 'c': - result = pclcluster(nrows, ncolumns, data, mask, weight, distmatrix, - dist, transpose); - break; - } - - /* Deallocate space for distance matrix, if it was allocated by treecluster */ - if(ldistmatrix) - { int i; - for (i = 1; i < nelements; i++) free(distmatrix[i]); - free (distmatrix); - } - - return result; -} - -/* ******************************************************************* */ - -static -void somworker (int nrows, int ncolumns, double** data, int** mask, - const double weights[], int transpose, int nxgrid, int nygrid, - double inittau, double*** celldata, int niter, char dist) - -{ const int nelements = (transpose==0) ? nrows : ncolumns; - const int ndata = (transpose==0) ? ncolumns : nrows; - int i, j; - double* stddata = calloc(nelements,sizeof(double)); - int** dummymask; - int ix, iy; - int* index; - int iter; - /* Maximum radius in which nodes are adjusted */ - double maxradius = sqrt(nxgrid*nxgrid+nygrid*nygrid); - - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - /* Calculate the standard deviation for each row or column */ - if (transpose==0) - { for (i = 0; i < nelements; i++) - { int n = 0; - for (j = 0; j < ndata; j++) - { if (mask[i][j]) - { double term = data[i][j]; - term = term * term; - stddata[i] += term; - n++; - } - } - if (stddata[i] > 0) stddata[i] = sqrt(stddata[i]/n); - else stddata[i] = 1; - } - } - else - { for (i = 0; i < nelements; i++) - { int n = 0; - for (j = 0; j < ndata; j++) - { if (mask[j][i]) - { double term = data[j][i]; - term = term * term; - stddata[i] += term; - n++; - } - } - if (stddata[i] > 0) stddata[i] = sqrt(stddata[i]/n); - else stddata[i] = 1; - } - } - - if (transpose==0) - { dummymask = malloc(nygrid*sizeof(int*)); - for (i = 0; i < nygrid; i++) - { dummymask[i] = malloc(ndata*sizeof(int)); - for (j = 0; j < ndata; j++) dummymask[i][j] = 1; - } - } - else - { dummymask = malloc(ndata*sizeof(int*)); - for (i = 0; i < ndata; i++) - { dummymask[i] = malloc(sizeof(int)); - dummymask[i][0] = 1; - } - } - - /* Randomly initialize the nodes */ - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { double sum = 0.; - for (i = 0; i < ndata; i++) - { double term = -1.0 + 2.0*uniform(); - celldata[ix][iy][i] = term; - sum += term * term; - } - sum = sqrt(sum/ndata); - for (i = 0; i < ndata; i++) celldata[ix][iy][i] /= sum; - } - } - - /* Randomize the order in which genes or arrays will be used */ - index = malloc(nelements*sizeof(int)); - for (i = 0; i < nelements; i++) index[i] = i; - for (i = 0; i < nelements; i++) - { j = (int) (i + (nelements-i)*uniform()); - ix = index[j]; - index[j] = index[i]; - index[i] = ix; - } - - /* Start the iteration */ - for (iter = 0; iter < niter; iter++) - { int ixbest = 0; - int iybest = 0; - int iobject = iter % nelements; - iobject = index[iobject]; - if (transpose==0) - { double closest = metric(ndata,data,celldata[ixbest], - mask,dummymask,weights,iobject,iybest,transpose); - double radius = maxradius * (1. - ((double)iter)/((double)niter)); - double tau = inittau * (1. - ((double)iter)/((double)niter)); - - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { double distance = - metric (ndata,data,celldata[ix], - mask,dummymask,weights,iobject,iy,transpose); - if (distance < closest) - { ixbest = ix; - iybest = iy; - closest = distance; - } - } - } - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { if (sqrt((ix-ixbest)*(ix-ixbest)+(iy-iybest)*(iy-iybest))0) - { sum = sqrt(sum/ndata); - for (i = 0; i < ndata; i++) celldata[ix][iy][i] /= sum; - } - } - } - } - } - else - { double closest; - double** celldatavector = malloc(ndata*sizeof(double*)); - double radius = maxradius * (1. - ((double)iter)/((double)niter)); - double tau = inittau * (1. - ((double)iter)/((double)niter)); - - for (i = 0; i < ndata; i++) - celldatavector[i] = &(celldata[ixbest][iybest][i]); - closest = metric(ndata,data,celldatavector, - mask,dummymask,weights,iobject,0,transpose); - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { double distance; - for (i = 0; i < ndata; i++) - celldatavector[i] = &(celldata[ixbest][iybest][i]); - distance = - metric (ndata,data,celldatavector, - mask,dummymask,weights,iobject,0,transpose); - if (distance < closest) - { ixbest = ix; - iybest = iy; - closest = distance; - } - } - } - free(celldatavector); - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { if (sqrt((ix-ixbest)*(ix-ixbest)+(iy-iybest)*(iy-iybest))0) - { sum = sqrt(sum/ndata); - for (i = 0; i < ndata; i++) celldata[ix][iy][i] /= sum; - } - } - } - } - } - } - if (transpose==0) - for (i = 0; i < nygrid; i++) free(dummymask[i]); - else - for (i = 0; i < ndata; i++) free(dummymask[i]); - free(dummymask); - free(stddata); - free(index); - return; -} - -/* ******************************************************************* */ - -static -void somassign (int nrows, int ncolumns, double** data, int** mask, - const double weights[], int transpose, int nxgrid, int nygrid, - double*** celldata, char dist, int clusterid[][2]) -/* Collect clusterids */ -{ const int ndata = (transpose==0) ? ncolumns : nrows; - int i,j; - - /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - if (transpose==0) - { int** dummymask = malloc(nygrid*sizeof(int*)); - for (i = 0; i < nygrid; i++) - { dummymask[i] = malloc(ncolumns*sizeof(int)); - for (j = 0; j < ncolumns; j++) dummymask[i][j] = 1; - } - for (i = 0; i < nrows; i++) - { int ixbest = 0; - int iybest = 0; - double closest = metric(ndata,data,celldata[ixbest], - mask,dummymask,weights,i,iybest,transpose); - int ix, iy; - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { double distance = - metric (ndata,data,celldata[ix], - mask,dummymask,weights,i,iy,transpose); - if (distance < closest) - { ixbest = ix; - iybest = iy; - closest = distance; - } - } - } - clusterid[i][0] = ixbest; - clusterid[i][1] = iybest; - } - for (i = 0; i < nygrid; i++) free(dummymask[i]); - free(dummymask); - } - else - { double** celldatavector = malloc(ndata*sizeof(double*)); - int** dummymask = malloc(nrows*sizeof(int*)); - int ixbest = 0; - int iybest = 0; - for (i = 0; i < nrows; i++) - { dummymask[i] = malloc(sizeof(int)); - dummymask[i][0] = 1; - } - for (i = 0; i < ncolumns; i++) - { double closest; - int ix, iy; - for (j = 0; j < ndata; j++) - celldatavector[j] = &(celldata[ixbest][iybest][j]); - closest = metric(ndata,data,celldatavector, - mask,dummymask,weights,i,0,transpose); - for (ix = 0; ix < nxgrid; ix++) - { for (iy = 0; iy < nygrid; iy++) - { double distance; - for(j = 0; j < ndata; j++) - celldatavector[j] = &(celldata[ix][iy][j]); - distance = metric(ndata,data,celldatavector, - mask,dummymask,weights,i,0,transpose); - if (distance < closest) - { ixbest = ix; - iybest = iy; - closest = distance; - } - } - } - clusterid[i][0] = ixbest; - clusterid[i][1] = iybest; - } - free(celldatavector); - for (i = 0; i < nrows; i++) free(dummymask[i]); - free(dummymask); - } - return; -} - -/* ******************************************************************* */ - -void somcluster (int nrows, int ncolumns, double** data, int** mask, - const double weight[], int transpose, int nxgrid, int nygrid, - double inittau, int niter, char dist, double*** celldata, int clusterid[][2]) -/* - -Purpose -======= - -The somcluster routine implements a self-organizing map (Kohonen) on a -rectangular grid, using a given set of vectors. The distance measure to be -used to find the similarity between genes and nodes is given by dist. - -Arguments -========= - -nrows (input) int -The number of rows in the data matrix, equal to the number of genes. - -ncolumns (input) int -The number of columns in the data matrix, equal to the number of microarrays. - -data (input) double[nrows][ncolumns] -The array containing the gene expression data. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If -mask[i][j] == 0, then data[i][j] is missing. - -weights (input) double[ncolumns] if transpose==0; - double[nrows] if transpose==1 -The weights that are used to calculate the distance. The length of this vector -is ncolumns if genes are being clustered, or nrows if microarrays are being -clustered. - -transpose (input) int -If transpose==0, the rows (genes) of the matrix are clustered. Otherwise, -columns (microarrays) of the matrix are clustered. - -nxgrid (input) int -The number of grid cells horizontally in the rectangular topology of clusters. - -nygrid (input) int -The number of grid cells horizontally in the rectangular topology of clusters. - -inittau (input) double -The initial value of tau, representing the neighborhood function. - -niter (input) int -The number of iterations to be performed. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -celldata (output) double[nxgrid][nygrid][ncolumns] if transpose==0; - double[nxgrid][nygrid][nrows] if tranpose==1 -The gene expression data for each node (cell) in the 2D grid. This can be -interpreted as the centroid for the cluster corresponding to that cell. If -celldata is NULL, then the centroids are not returned. If celldata is not -NULL, enough space should be allocated to store the centroid data before callingsomcluster. - -clusterid (output), int[nrows][2] if transpose==0; - int[ncolumns][2] if transpose==1 -For each item (gene or microarray) that is clustered, the coordinates of the -cell in the 2D grid to which the item was assigned. If clusterid is NULL, the -cluster assignments are not returned. If clusterid is not NULL, enough memory -should be allocated to store the clustering information before calling -somcluster. - -======================================================================== -*/ -{ const int nobjects = (transpose==0) ? nrows : ncolumns; - const int ndata = (transpose==0) ? ncolumns : nrows; - int i,j; - const int lcelldata = (celldata==NULL) ? 0 : 1; - - if (nobjects < 2) return; - - if (lcelldata==0) - { celldata = malloc(nxgrid*nygrid*ndata*sizeof(double**)); - for (i = 0; i < nxgrid; i++) - { celldata[i] = malloc(nygrid*ndata*sizeof(double*)); - for (j = 0; j < nygrid; j++) - celldata[i][j] = malloc(ndata*sizeof(double)); - } - } - - somworker (nrows, ncolumns, data, mask, weight, transpose, nxgrid, nygrid, - inittau, celldata, niter, dist); - if (clusterid) - somassign (nrows, ncolumns, data, mask, weight, transpose, - nxgrid, nygrid, celldata, dist, clusterid); - if(lcelldata==0) - { for (i = 0; i < nxgrid; i++) - for (j = 0; j < nygrid; j++) - free(celldata[i][j]); - for (i = 0; i < nxgrid; i++) - free(celldata[i]); - free(celldata); - } - return; -} - -/* ******************************************************************** */ - -double clusterdistance (int nrows, int ncolumns, double** data, - int** mask, double weight[], int n1, int n2, int index1[], int index2[], - char dist, char method, int transpose) - -/* -Purpose -======= - -The clusterdistance routine calculates the distance between two clusters -containing genes or microarrays using the measured gene expression vectors. The -distance between clusters, given the genes/microarrays in each cluster, can be -defined in several ways. Several distance measures can be used. - -The routine returns the distance in double precision. -If the parameter transpose is set to a nonzero value, the clusters are -interpreted as clusters of microarrays, otherwise as clusters of gene. - -Arguments -========= - -nrows (input) int -The number of rows (i.e., the number of genes) in the gene expression data -matrix. - -ncolumns (input) int -The number of columns (i.e., the number of microarrays) in the gene expression -data matrix. - -data (input) double[nrows][ncolumns] -The array containing the data of the vectors. - -mask (input) int[nrows][ncolumns] -This array shows which data values are missing. If mask[i][j]==0, then -data[i][j] is missing. - -weight (input) double[ncolumns] if transpose==0; - double[nrows] if transpose==1 -The weights that are used to calculate the distance. - -n1 (input) int -The number of elements in the first cluster. - -n2 (input) int -The number of elements in the second cluster. - -index1 (input) int[n1] -Identifies which genes/microarrays belong to the first cluster. - -index2 (input) int[n2] -Identifies which genes/microarrays belong to the second cluster. - -dist (input) char -Defines which distance measure is used, as given by the table: -dist=='e': Euclidean distance -dist=='b': City-block distance -dist=='c': correlation -dist=='a': absolute value of the correlation -dist=='u': uncentered correlation -dist=='x': absolute uncentered correlation -dist=='s': Spearman's rank correlation -dist=='k': Kendall's tau -For other values of dist, the default (Euclidean distance) is used. - -method (input) char -Defines how the distance between two clusters is defined, given which genes -belong to which cluster: -method=='a': the distance between the arithmetic means of the two clusters -method=='m': the distance between the medians of the two clusters -method=='s': the smallest pairwise distance between members of the two clusters -method=='x': the largest pairwise distance between members of the two clusters -method=='v': average of the pairwise distances between members of the clusters - -transpose (input) int -If transpose is equal to zero, the distances between the rows is -calculated. Otherwise, the distances between the columns is calculated. -The former is needed when genes are being clustered; the latter is used -when microarrays are being clustered. - -======================================================================== -*/ -{ /* Set the metric function as indicated by dist */ - double (*metric) - (int, double**, double**, int**, int**, const double[], int, int, int) = - setmetric(dist); - - /* if one or both clusters are empty, return */ - if (n1 < 1 || n2 < 1) return -1.0; - /* Check the indices */ - if (transpose==0) - { int i; - for (i = 0; i < n1; i++) - { int index = index1[i]; - if (index < 0 || index >= nrows) return -1.0; - } - for (i = 0; i < n2; i++) - { int index = index2[i]; - if (index < 0 || index >= nrows) return -1.0; - } - } - else - { int i; - for (i = 0; i < n1; i++) - { int index = index1[i]; - if (index < 0 || index >= ncolumns) return -1.0; - } - for (i = 0; i < n2; i++) - { int index = index2[i]; - if (index < 0 || index >= ncolumns) return -1.0; - } - } - - switch (method) - { case 'a': - { /* Find the center */ - int i,j,k; - if (transpose==0) - { double distance; - double* cdata[2]; - int* cmask[2]; - int* count[2]; - count[0] = calloc(ncolumns,sizeof(int)); - count[1] = calloc(ncolumns,sizeof(int)); - cdata[0] = calloc(ncolumns,sizeof(double)); - cdata[1] = calloc(ncolumns,sizeof(double)); - cmask[0] = malloc(ncolumns*sizeof(int)); - cmask[1] = malloc(ncolumns*sizeof(int)); - for (i = 0; i < n1; i++) - { k = index1[i]; - for (j = 0; j < ncolumns; j++) - if (mask[k][j] != 0) - { cdata[0][j] = cdata[0][j] + data[k][j]; - count[0][j] = count[0][j] + 1; - } - } - for (i = 0; i < n2; i++) - { k = index2[i]; - for (j = 0; j < ncolumns; j++) - if (mask[k][j] != 0) - { cdata[1][j] = cdata[1][j] + data[k][j]; - count[1][j] = count[1][j] + 1; - } - } - for (i = 0; i < 2; i++) - for (j = 0; j < ncolumns; j++) - { if (count[i][j]>0) - { cdata[i][j] = cdata[i][j] / count[i][j]; - cmask[i][j] = 1; - } - else - cmask[i][j] = 0; - } - distance = - metric (ncolumns,cdata,cdata,cmask,cmask,weight,0,1,0); - for (i = 0; i < 2; i++) - { free (cdata[i]); - free (cmask[i]); - free (count[i]); - } - return distance; - } - else - { double distance; - int** count = malloc(nrows*sizeof(int*)); - double** cdata = malloc(nrows*sizeof(double*)); - int** cmask = malloc(nrows*sizeof(int*)); - for (i = 0; i < nrows; i++) - { count[i] = calloc(2,sizeof(int)); - cdata[i] = calloc(2,sizeof(double)); - cmask[i] = malloc(2*sizeof(int)); - } - for (i = 0; i < n1; i++) - { k = index1[i]; - for (j = 0; j < nrows; j++) - { if (mask[j][k] != 0) - { cdata[j][0] = cdata[j][0] + data[j][k]; - count[j][0] = count[j][0] + 1; - } - } - } - for (i = 0; i < n2; i++) - { k = index2[i]; - for (j = 0; j < nrows; j++) - { if (mask[j][k] != 0) - { cdata[j][1] = cdata[j][1] + data[j][k]; - count[j][1] = count[j][1] + 1; - } - } - } - for (i = 0; i < nrows; i++) - for (j = 0; j < 2; j++) - if (count[i][j]>0) - { cdata[i][j] = cdata[i][j] / count[i][j]; - cmask[i][j] = 1; - } - else - cmask[i][j] = 0; - distance = metric (nrows,cdata,cdata,cmask,cmask,weight,0,1,1); - for (i = 0; i < nrows; i++) - { free (count[i]); - free (cdata[i]); - free (cmask[i]); - } - free (count); - free (cdata); - free (cmask); - return distance; - } - } - case 'm': - { int i, j, k; - if (transpose==0) - { double distance; - double* temp = malloc(nrows*sizeof(double)); - double* cdata[2]; - int* cmask[2]; - for (i = 0; i < 2; i++) - { cdata[i] = malloc(ncolumns*sizeof(double)); - cmask[i] = malloc(ncolumns*sizeof(int)); - } - for (j = 0; j < ncolumns; j++) - { int count = 0; - for (k = 0; k < n1; k++) - { i = index1[k]; - if (mask[i][j]) - { temp[count] = data[i][j]; - count++; - } - } - if (count>0) - { cdata[0][j] = median (count,temp); - cmask[0][j] = 1; - } - else - { cdata[0][j] = 0.; - cmask[0][j] = 0; - } - } - for (j = 0; j < ncolumns; j++) - { int count = 0; - for (k = 0; k < n2; k++) - { i = index2[k]; - if (mask[i][j]) - { temp[count] = data[i][j]; - count++; - } - } - if (count>0) - { cdata[1][j] = median (count,temp); - cmask[1][j] = 1; - } - else - { cdata[1][j] = 0.; - cmask[1][j] = 0; - } - } - distance = metric (ncolumns,cdata,cdata,cmask,cmask,weight,0,1,0); - for (i = 0; i < 2; i++) - { free (cdata[i]); - free (cmask[i]); - } - free(temp); - return distance; - } - else - { double distance; - double* temp = malloc(ncolumns*sizeof(double)); - double** cdata = malloc(nrows*sizeof(double*)); - int** cmask = malloc(nrows*sizeof(int*)); - for (i = 0; i < nrows; i++) - { cdata[i] = malloc(2*sizeof(double)); - cmask[i] = malloc(2*sizeof(int)); - } - for (j = 0; j < nrows; j++) - { int count = 0; - for (k = 0; k < n1; k++) - { i = index1[k]; - if (mask[j][i]) - { temp[count] = data[j][i]; - count++; - } - } - if (count>0) - { cdata[j][0] = median (count,temp); - cmask[j][0] = 1; - } - else - { cdata[j][0] = 0.; - cmask[j][0] = 0; - } - } - for (j = 0; j < nrows; j++) - { int count = 0; - for (k = 0; k < n2; k++) - { i = index2[k]; - if (mask[j][i]) - { temp[count] = data[j][i]; - count++; - } - } - if (count>0) - { cdata[j][1] = median (count,temp); - cmask[j][1] = 1; - } - else - { cdata[j][1] = 0.; - cmask[j][1] = 0; - } - } - distance = metric (nrows,cdata,cdata,cmask,cmask,weight,0,1,1); - for (i = 0; i < nrows; i++) - { free (cdata[i]); - free (cmask[i]); - } - free(cdata); - free(cmask); - free(temp); - return distance; - } - } - case 's': - { int i1, i2, j1, j2; - const int n = (transpose==0) ? ncolumns : nrows; - double mindistance = DBL_MAX; - for (i1 = 0; i1 < n1; i1++) - for (i2 = 0; i2 < n2; i2++) - { double distance; - j1 = index1[i1]; - j2 = index2[i2]; - distance = metric (n,data,data,mask,mask,weight,j1,j2,transpose); - if (distance < mindistance) mindistance = distance; - } - return mindistance; - } - case 'x': - { int i1, i2, j1, j2; - const int n = (transpose==0) ? ncolumns : nrows; - double maxdistance = 0; - for (i1 = 0; i1 < n1; i1++) - for (i2 = 0; i2 < n2; i2++) - { double distance; - j1 = index1[i1]; - j2 = index2[i2]; - distance = metric (n,data,data,mask,mask,weight,j1,j2,transpose); - if (distance > maxdistance) maxdistance = distance; - } - return maxdistance; - } - case 'v': - { int i1, i2, j1, j2; - const int n = (transpose==0) ? ncolumns : nrows; - double distance = 0; - for (i1 = 0; i1 < n1; i1++) - for (i2 = 0; i2 < n2; i2++) - { j1 = index1[i1]; - j2 = index2[i2]; - distance += metric (n,data,data,mask,mask,weight,j1,j2,transpose); - } - distance /= (n1*n2); - return distance; - } - } - /* Never get here */ - return -2.0; -} diff --git a/Addons/HMat/CClusteringLibrary/cluster.h b/Addons/HMat/CClusteringLibrary/cluster.h deleted file mode 100644 index 6b233f97f334562b6332fcbde4b1d983cb0c9d7c..0000000000000000000000000000000000000000 --- a/Addons/HMat/CClusteringLibrary/cluster.h +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************/ -/* The C Clustering Library. - * Copyright (C) 2002 Michiel Jan Laurens de Hoon. - * - * This library was written at the Laboratory of DNA Information Analysis, - * Human Genome Center, Institute of Medical Science, University of Tokyo, - * 4-6-1 Shirokanedai, Minato-ku, Tokyo 108-8639, Japan. - * Contact: mdehoon 'AT' gsc.riken.jp - * - * Permission to use, copy, modify, and distribute this software and its - * documentation with or without modifications and for any purpose and - * without fee is hereby granted, provided that any copyright notices - * appear in all copies and that both those copyright notices and this - * permission notice appear in supporting documentation, and that the - * names of the contributors or copyright holders not be used in - * advertising or publicity pertaining to distribution of the software - * without specific prior permission. - * - * THE CONTRIBUTORS AND COPYRIGHT HOLDERS OF THIS SOFTWARE DISCLAIM ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE - * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT - * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE - * OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -// @SCALFMM_PRIVATE - -#ifdef WINDOWS -# include -#endif - -#define CLUSTERVERSION "1.52a" - -/* Chapter 2 */ -double clusterdistance (int nrows, int ncolumns, double** data, int** mask, - double weight[], int n1, int n2, int index1[], int index2[], char dist, - char method, int transpose); -double** distancematrix (int ngenes, int ndata, double** data, - int** mask, double* weight, char dist, int transpose); - -/* Chapter 3 */ -int getclustercentroids(int nclusters, int nrows, int ncolumns, - double** data, int** mask, int clusterid[], double** cdata, int** cmask, - int transpose, char method); -void getclustermedoids(int nclusters, int nelements, double** distance, - int clusterid[], int centroids[], double errors[]); -void kcluster (int nclusters, int ngenes, int ndata, double** data, - int** mask, double weight[], int transpose, int npass, char method, char dist, - int clusterid[], double* error, int* ifound); -void kmedoids (int nclusters, int nelements, double** distance, - int npass, int clusterid[], double* error, int* ifound); - -/* Chapter 4 */ -typedef struct {int left; int right; double distance;} Node; -/* - * A Node struct describes a single node in a tree created by hierarchical - * clustering. The tree can be represented by an array of n Node structs, - * where n is the number of elements minus one. The integers left and right - * in each Node struct refer to the two elements or subnodes that are joined - * in this node. The original elements are numbered 0..nelements-1, and the - * nodes -1..-(nelements-1). For each node, distance contains the distance - * between the two subnodes that were joined. - */ - -Node* treecluster (int nrows, int ncolumns, double** data, int** mask, - double weight[], int transpose, char dist, char method, double** distmatrix); -void cuttree (int nelements, Node* tree, int nclusters, int clusterid[]); - -/* Chapter 5 */ -void somcluster (int nrows, int ncolumns, double** data, int** mask, - const double weight[], int transpose, int nxnodes, int nynodes, - double inittau, int niter, char dist, double*** celldata, - int clusterid[][2]); - -/* Chapter 6 */ -int pca(int m, int n, double** u, double** v, double* w); - -/* Utility routines, currently undocumented */ -void sort(int n, const double data[], int index[]); -double mean(int n, double x[]); -double median (int n, double x[]); - -double* calculate_weights(int nrows, int ncolumns, double** data, int** mask, - double weights[], int transpose, char dist, double cutoff, double exponent); diff --git a/Addons/HMat/CClusteringLibrary/cluster.pdf b/Addons/HMat/CClusteringLibrary/cluster.pdf deleted file mode 100644 index c55ed940a4aa7d298d37acb87cd459fd25d01a57..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/CClusteringLibrary/cluster.pdf and /dev/null differ diff --git a/Addons/HMat/CMakeLists.txt b/Addons/HMat/CMakeLists.txt deleted file mode 100644 index 0c779fc9a64d4d4a979e68eadeae346b694bc6dc..0000000000000000000000000000000000000000 --- a/Addons/HMat/CMakeLists.txt +++ /dev/null @@ -1,112 +0,0 @@ -# check if compiling into source directories -STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" insource) -if(insource) - MESSAGE(FATAL_ERROR "${PROJECT_NAME} requires an out of source build. Goto ./Build and tapes cmake ../") -endif(insource) - -project(ADDONS_HMAT_SCALFMM CXX C) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SCALFMM_CXX_FLAGS}") - -# Active language -# ----------------------- -ENABLE_LANGUAGE(CXX C) -MESSAGE(STATUS " CXX ${CMAKE_CXX_COMPILER_ID}" ) - -# Options -OPTION( SCALFMM_ADDON_HMAT "Set to ON to build ScalFMM HMat interface" OFF ) - -# if ask to build addon -if(SCALFMM_ADDON_HMAT) - list(APPEND FUSE_LIST "SCOTCH") - set(SCOTCH_NOT_FOUND $ENV{SCOTCH_LIB}) - if(NOT SCOTCH_NOT_FOUND) - MESSAGE(STATUS " SCOTCH not found " ) - else() - OPTION( SCALFMM_USE_SCOTCH "Set to ON to use scotch" ON ) - if (SCALFMM_USE_SCOTCH) - include_directories($ENV{SCOTCH_INC}) - SET(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};-L$ENV{SCOTCH_LIB};-lscotch;-lscotcherr") - endif() - endif() - - # first build lib scalfmmhmat - set(LIBRARY_OUTPUT_PATH ../lib/${CMAKE_BUILD_TYPE}) - - # Searching all cpp file - file( GLOB_RECURSE source_lib_files Src/*.cpp ) - - # Adding cpp files to project - add_library( scalfmmhmat STATIC ${source_lib_files} ) - - # Add blas library (even if it is set to off) - target_link_libraries( scalfmmhmat scalfmm) - - # Adding the entire project dir as an include dir - INCLUDE_DIRECTORIES( - ${SCALFMM_BINARY_DIR}/Src - ${SCALFMM_SOURCE_DIR}/Src - ${SCALFMM_INCLUDES} - ) - - # Install lib - install( TARGETS scalfmmhmat ARCHIVE DESTINATION lib ) - - # Install headers - SET(my_include_dirs "Src/Blocks" "Src/Clustering" "Src/Containers" "Src/Utils" "Src/Viewers" "CClusteringLibrary") - - FOREACH(my_dir ${my_include_dirs}) - file(GLOB - hpp_in_dir - ${my_dir}/*.hpp ${my_dir}/*.h - ) - INSTALL( FILES ${hpp_in_dir} DESTINATION include/ScalFmm/HMat/${my_dir} ) - ENDFOREACH() - - # Add C Clustering Library - file( GLOB_RECURSE ccl_lib_files CClusteringLibrary/*.c ) - add_library( cclusteringlib STATIC ${ccl_lib_files} ) - INCLUDE_DIRECTORIES(CClusteringLibrary/) - target_link_libraries( cclusteringlib scalfmm) - install( TARGETS cclusteringlib ARCHIVE DESTINATION lib ) - - # Tests - file( GLOB_RECURSE source_tests_files Tests/*.cpp ) - INCLUDE_DIRECTORIES( ${SCALFMM_BINARY_DIR}/Src ) - - # Then build test files - SET(hmat_list_execs "") - foreach(exec ${source_tests_files}) - get_filename_component( - execname ${exec} - NAME_WE - ) - - set(compile_exec "TRUE") - - foreach(fuse_key ${FUSE_LIST}) - file(STRINGS "${exec}" lines_fuse REGEX "@FUSE_${fuse_key}") - if(lines_fuse) - if( NOT SCALFMM_USE_${fuse_key} ) - MESSAGE( STATUS "This needs ${fuse_key} = ${exec}" ) - set(compile_exec "FALSE") - endif() - endif() - endforeach() - - # Dependency are OK - if( compile_exec ) - add_executable( ${execname} ${exec} ) - # link to scalfmm and scalfmmhmat and cclusteringlib - target_link_libraries( - ${execname} - ${scalfmm_lib} - scalfmmhmat - cclusteringlib - ${SCALFMM_LIBRARIES} - ) - LIST(APPEND hmat_list_execs ${execname}) - endif() - endforeach(exec) - - add_custom_target(hmat DEPENDS ${hmat_list_execs}) -endif() diff --git a/Addons/HMat/Data/first_reads_1k-fmr-covar.bin b/Addons/HMat/Data/first_reads_1k-fmr-covar.bin deleted file mode 100644 index e54c603228532de21362fcd4fbc3e1cb79228976..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/first_reads_1k-fmr-covar.bin and /dev/null differ diff --git a/Addons/HMat/Data/first_reads_1k-fmr-dissw.bin b/Addons/HMat/Data/first_reads_1k-fmr-dissw.bin deleted file mode 100644 index d3dc81aabbd1c27e04339fe21a4e32a3ae45f56f..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/first_reads_1k-fmr-dissw.bin and /dev/null differ diff --git a/Addons/HMat/Data/unitCube1000.bfma b/Addons/HMat/Data/unitCube1000.bfma deleted file mode 100644 index 7d339bb4221da859d90dc8ac141cc98dc81fd3cc..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitCube1000.bfma and /dev/null differ diff --git a/Addons/HMat/Data/unitCube1000.bin b/Addons/HMat/Data/unitCube1000.bin deleted file mode 100644 index 80ad7e23961f2026597f50a4afeff410fcabbec3..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitCube1000.bin and /dev/null differ diff --git a/Addons/HMat/Data/unitCube1000_GAUSS100.bin b/Addons/HMat/Data/unitCube1000_GAUSS100.bin deleted file mode 100644 index 4d523ead7f788c4f4fe5b224e7a95ade5af99cab..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitCube1000_GAUSS100.bin and /dev/null differ diff --git a/Addons/HMat/Data/unitCube1000_ONE_OVER_R.bin b/Addons/HMat/Data/unitCube1000_ONE_OVER_R.bin deleted file mode 100644 index 7e122e73f91c56279e76618e3960b4f6b9c39d8b..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitCube1000_ONE_OVER_R.bin and /dev/null differ diff --git a/Addons/HMat/Data/unitCube5000.bfma b/Addons/HMat/Data/unitCube5000.bfma deleted file mode 100644 index 3928e4f8bfaeb62618e50bd2fe548c871025b554..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitCube5000.bfma and /dev/null differ diff --git a/Addons/HMat/Data/unitSphere1000.bfma b/Addons/HMat/Data/unitSphere1000.bfma deleted file mode 100644 index 46e62a6c759c004aa78b70a0402bac56a4882c62..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitSphere1000.bfma and /dev/null differ diff --git a/Addons/HMat/Data/unitSphere1000.bin b/Addons/HMat/Data/unitSphere1000.bin deleted file mode 100644 index 9e9464f375c02f5600ee5d58528cb5a94096835f..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitSphere1000.bin and /dev/null differ diff --git a/Addons/HMat/Data/unitSphere1000_GAUSS100.bin b/Addons/HMat/Data/unitSphere1000_GAUSS100.bin deleted file mode 100644 index c51d7419490007eb0c1c3f5cb766e7aeaee9231d..0000000000000000000000000000000000000000 Binary files a/Addons/HMat/Data/unitSphere1000_GAUSS100.bin and /dev/null differ diff --git a/Addons/HMat/Src/Blocks/FACABlock.hpp b/Addons/HMat/Src/Blocks/FACABlock.hpp deleted file mode 100644 index b9789c3b63b384461151b1def85b055c7ebc2b65..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Blocks/FACABlock.hpp +++ /dev/null @@ -1,184 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -// -// @SCALFMM_PRIVATE -// -#ifndef FACABLOCK_HPP -#define FACABLOCK_HPP - -#include "Utils/FBlas.hpp" -#include "Utils/FAca.hpp" - - -/*! Choose either \a FULLY_PIVOTED_ACA or \a PARTIALLY_PIVOTED_ACA */ -#define FULLY_PIVOTED_ACA -//#define PARTIALLY_PIVOTED_ACA - -/*! Choose \a RECOMPRESSED_ACA */ -#define RECOMPRESSED_ACA - - -template -class FACABlock{ -protected: - // members - FReal* block; - FReal* U; - FReal* VT; - int nbRows; - int nbCols; - int level; - unsigned int rank; - FReal accuracy; - FACABlock(const FACABlock&) = delete; - FACABlock& operator=(const FACABlock&) = delete; - -public: - FACABlock() - : block(nullptr), U(nullptr), VT(nullptr), nbRows(0), nbCols(0), level(0), rank(0), accuracy(FMath::pow(FReal(10.0),static_cast(-ORDER))) { - } - - // ctor - template - void fill(const ViewerClass& viewer, const int inLevel){ - clear(); - // Allocate memory - level = inLevel; - nbRows = viewer.getNbRows(); - nbCols = viewer.getNbCols(); - - -#if (defined FULLY_PIVOTED_ACA) - block = new FReal[nbRows*nbCols]; - - for(int idxRow = 0 ; idxRow < nbRows ; ++idxRow){ - for(int idxCol = 0 ; idxCol < nbCols ; ++idxCol){ - block[idxCol*nbRows+idxRow] = viewer.getValue(idxRow,idxCol); - } - } -#endif - - - // SVD specific (col major) - rank = std::min(nbRows,nbCols); - //S = new FReal[rank]; - FReal* _U ;// = new FReal[nbRows*nbCols]; // Call to computeSVD() copies block into U - FReal* _V;// = new FReal[rank*nbCols]; - -#if (defined FULLY_PIVOTED_ACA) - - // Perform fully pivoted ACA - FAca::fACA(block, nbRows, nbCols, accuracy, _U, _V, rank); - -#elif (defined PARTIAL_PIVOTED_ACA) - - // TODO - // Perform partially pivoted ACA - //FAca::fACA(viewer, nbRows, nbCols, accuracy, _U, _V, rank); - -#endif - // display rank - std::cout << "rank after ACA=" << rank << " (" << nbRows << "," << nbCols << ")" << std::endl; - -#if (defined RECOMPRESSED_ACA) - - // Recompression by QR+SVD - FAca::recompress(_U,_V,nbRows,nbCols,accuracy,U,VT,rank); - // display rank after recompression - std::cout << " rank after QR+SVD=" << rank << std::endl; - -#else - - // Resize U and VT - U = new FReal[nbRows*rank]; - for(int idxRow = 0 ; idxRow < nbRows ; ++idxRow) - for(int idxCol = 0 ; idxCol < rank ; ++idxCol) - U[idxCol*nbRows+idxRow] = _U[idxCol*nbRows+idxRow]; - - VT = new FReal[rank*nbCols]; - for(int idxRow = 0 ; idxRow < rank ; ++idxRow) - for(int idxCol = 0 ; idxCol < nbCols ; ++idxCol) - VT[idxCol*rank+idxRow] = _V[idxRow*nbCols+idxCol]; // transposition - -#endif - - // Free memory - delete [] _U; - delete [] _V; - - }; - - // dtor - ~FACABlock(){ - // Free memory - clear(); - }; - - void clear(){ - nbRows = 0; - nbCols = 0; - level = 0; - rank = 0; - delete[] block; - block = 0; - delete[] U; - U = 0; - delete[] VT; - VT = 0; - } - - void gemv(FReal res[], const FReal vec[], const FReal scale = FReal(1.)) const { - - //// Apply (dense) block - //FReal* res_dense = new FReal[nbRows]; - //FBlas::copy(nbRows,res,res_dense); - //FBlas::gemva(nbRows, nbCols, scale, const_cast(block), const_cast(vec), res_dense); - - // Apply low-rank block - FReal* VTvec = new FReal[rank]; - FBlas::setzero(rank,VTvec); - - // Apply VT - FBlas::gemv(rank, nbCols, scale, const_cast(VT), const_cast(vec), VTvec); - - // Apply U - FBlas::gemva(nbRows, rank, scale, const_cast(U), const_cast(VTvec), res); - - } - - void gemm(FReal res[], const FReal mat[], const int nbRhs, const FReal scale = FReal(1.)) const { - - //// Apply (dense) block - //FBlas::gemma(nbRows, nbCols, nbRhs, scale, const_cast(block), nbRows, const_cast(mat), nbCols, res, nbRows); - - // Apply low-rank block - FReal* VTmat = new FReal[nbCols*nbRhs]; - // Apply VT - FBlas::gemm(rank, nbCols, nbRhs, scale, const_cast(VT), rank, const_cast(mat), nbCols, VTmat, rank); - // Apply U - FBlas::gemma(nbRows, rank, nbRhs, scale, const_cast(U), nbRows, const_cast(VTmat), rank, res, nbRows); - - } - - int getRank() const{ - return rank; - } - -}; - -#endif // FACABLOCK_HPP - -// [--END--] diff --git a/Addons/HMat/Src/Blocks/FDenseBlock.hpp b/Addons/HMat/Src/Blocks/FDenseBlock.hpp deleted file mode 100644 index 7bf42da75484f3cc143b5e3697a8318227fb239b..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Blocks/FDenseBlock.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -// -// @SCALFMM_PRIVATE -// -#ifndef FDENSEBLOCK_HPP -#define FDENSEBLOCK_HPP - -#include "Utils/FBlas.hpp" - -template -class FDenseBlock{ -protected: - // members - FReal* block; - int nbRows; - int nbCols; - int level; - - FDenseBlock(const FDenseBlock&) = delete; - FDenseBlock& operator=(const FDenseBlock&) = delete; - -public: - FDenseBlock() - : block(nullptr), nbRows(0), nbCols(0), level(0) { - } - - // ctor - template - void fill(const ViewerClass& viewer, const int inLevel){ - clear(); - // Allocate memory - level = inLevel; - nbRows = viewer.getNbRows(); - nbCols = viewer.getNbCols(); - block = new FReal[nbRows*nbCols]; - - for(int idxRow = 0 ; idxRow < nbRows ; ++idxRow){ - for(int idxCol = 0 ; idxCol < nbCols ; ++idxCol){ - block[idxCol*nbRows+idxRow] = viewer.getValue(idxRow,idxCol); - } - } - }; - - void resize(const int inNbRow, const int inNbCol){ - if(inNbRow != nbRows || - inNbCol != nbCols){ - clear(); - nbRows = inNbRow; - nbCols = inNbCol; - block = new FReal[nbRows*nbCols]; - } - memset(block, 0, sizeof(FReal)*nbRows*nbCols); - } - - // dtor - ~FDenseBlock(){ - // Free memory - clear(); - }; - - void clear(){ - nbRows = 0; - nbCols = 0; - nbCols = 0; - delete[] block; - block = 0; - } - - int getNbRows() const{ - return nbRows; - } - - int getNbCols() const{ - return nbCols; - } - - FReal getValue(const int idxRow, const int idxCol) const{ - return block[idxCol*nbRows+idxRow]; - } - - FReal& getValue(const int idxRow, const int idxCol) { - return block[idxCol*nbRows+idxRow]; - } - - void setValue(const int idxRow, const int idxCol, const FReal& val) { - block[idxCol*nbRows+idxRow] = val; - } - - void gemv(FReal res[], const FReal vec[], const FReal scale = FReal(1.)) const { - FBlas::gemva(nbRows, nbCols, scale, const_cast(block), const_cast(vec), res); - } - - void gemm(FReal res[], const FReal mat[], const int nbRhs, const FReal scale = FReal(1.)) const { - FBlas::gemma(nbRows, nbCols, nbRhs, scale, const_cast(block), nbRows, const_cast(mat), nbCols, res, nbRows); - } -}; - -#endif // FDENSEBLOCK_HPP - -// [--END--] diff --git a/Addons/HMat/Src/Blocks/FSVDBlock.hpp b/Addons/HMat/Src/Blocks/FSVDBlock.hpp deleted file mode 100644 index 8500c2df35cce6f9a196c867014854035e51eac4..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Blocks/FSVDBlock.hpp +++ /dev/null @@ -1,238 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -// -// @SCALFMM_PRIVATE -// -#ifndef FSVDBLOCK_HPP -#define FSVDBLOCK_HPP - -#include "Utils/FBlas.hpp" - -/* - * Compute SVD $A=USV'$ and return $V'$, $S$ and $U$. - * \param A contains input M x N matrix to be decomposed - * \param S contains singular values $S$ - * \param U contains $U$ - * \param VT contains $V'$ - */ -template -static void computeSVD(const FSize nbRows, const FSize nbCols, const FReal* A, FReal* S, FReal* U, FReal* VT){ - // verbose - const bool verbose = false; - // copy A - //is_int(size*size); - FBlas::copy(int(nbRows*nbCols),A,U); - // init SVD - const FSize minMN = std::min(nbRows,nbCols); - const FSize maxMN = std::max(nbRows,nbCols); - //const FSize LWORK = 2*4*minMN; // for square matrices - const FSize LWORK = 2*std::max(3*minMN+maxMN, 5*minMN); - FReal *const WORK = new FReal [LWORK]; - // singular value decomposition - if(verbose) std::cout << "\nPerform SVD..."; - // SO means that first min(m,n) lines of U overwritten on VT and V' on U (A=VTSU) - // AA means all lines - // nothing means OS (the opposite of SO, A=USVT) - //is_int(size); is_int(LWORK); - const unsigned int INFOSVD - = FBlas::gesvd(int(nbRows), int(nbCols), U, S, VT, int(minMN)/*ldVT*/, - int(LWORK), WORK); - if(verbose) { - if(INFOSVD!=0) {std::cout << " failed!" << std::endl;} - else {std::cout << " succeed!" << std::endl;} - } - // free memory - delete[] WORK; -} - - -/* - * Compute SVD $A=USV'$ and return $V'$, $S$ and $U$. - * \param - */ -template -static void computeNumericalRank(int &rank, const FReal* S, const FReal epsilon){ - // verbose - const bool verbose = false; - - // init - const FSize maxRank = rank; - FReal sumSigma2 = FReal(0.0); - for(int idxRow = 0 ; idxRow < rank ; ++idxRow) - sumSigma2+=S[idxRow]*S[idxRow]; - FReal SqrtSumSigma2 = std::sqrt(sumSigma2); - - // set rank to 1 - rank = 1; - // increase - FReal sumSigma2r = S[0]*S[0]; - while(std::sqrt(sumSigma2r)<(FReal(1.)-epsilon)*SqrtSumSigma2 && rank(block), const_cast(vec), res_dense); - - // Apply low-rank block - FReal* VTvec = new FReal[rank]; - FBlas::setzero(rank,VTvec); - - // Apply VT - FBlas::gemv(rank, nbCols, scale, const_cast(VT), const_cast(vec), VTvec); - - // Apply S - for(int idxS = 0 ; idxS < rank ; ++idxS) - VTvec[idxS]*=S[idxS]; - - // Apply U - FBlas::gemva(nbRows, rank, scale, const_cast(U), const_cast(VTvec), res); - - } - - void gemm(FReal res[], const FReal mat[], const int nbRhs, const FReal scale = FReal(1.)) const { - - //// Apply (dense) block - //FBlas::gemma(nbRows, nbCols, nbRhs, scale, const_cast(block), nbRows, const_cast(mat), nbCols, res, nbRows); - - // Apply low-rank block - FReal* VTmat = new FReal[nbCols*nbRhs]; - // Apply VT - FBlas::gemm(rank, nbCols, nbRhs, scale, const_cast(VT), rank, const_cast(mat), nbCols, VTmat, rank); - // Apply S - for(int idxRow = 0 ; idxRow < rank ; ++idxRow) - for(int idxRhs = 0 ; idxRhs < nbRhs ; ++idxRhs) - VTmat[idxRhs*rank+idxRow]*=S[idxRow]; - // Apply U - FBlas::gemma(nbRows, rank, nbRhs, scale, const_cast(U), nbRows, const_cast(VTmat), rank, res, nbRows); - - } - - int getRank() const{ - return rank; - } -}; - -#endif // FSVDBLOCK_HPP - -// [--END--] diff --git a/Addons/HMat/Src/Clustering/FCCLKCluster.hpp b/Addons/HMat/Src/Clustering/FCCLKCluster.hpp deleted file mode 100644 index bb895f199d461f473a706927145b188d0d9a0170..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Clustering/FCCLKCluster.hpp +++ /dev/null @@ -1,213 +0,0 @@ -// @SCALFMM_PRIVATE - -#ifndef FCCLKCLUSTER_HPP -#define FCCLKCLUSTER_HPP - -#include "./Utils/FGlobal.hpp" -#include "./Utils/FAssert.hpp" -#include "./Utils/FMath.hpp" -#include "../Utils/FHUtils.hpp" - -#include -#include -#include -#include -#include -#include - -extern "C" { -#include -} - - -namespace CCL { - enum ClusterCenterMethod { - CCL_CCM_ARITHMETIC_MEAN, - CCL_CCM_MEDIAN, - CCL_CCM_DUMMY - }; - - inline char ClusterCenterMethodToChar(const ClusterCenterMethod method){ - switch (method) { - case CCL_CCM_ARITHMETIC_MEAN: - return 'a'; - break; - case CCL_CCM_MEDIAN: - return 'm'; - break; - default: - break; - } - return '?'; - } - - enum Distance { - CCL_DIST_MEAN, - CCL_DIST_MEDIAN, - CCL_DIST_SHORTEST, - CCL_DIST_LONGEST, - CCL_DIST_AVG, - CCL_DIST_DUMMY - }; - - inline char DistanceToChar(const Distance method){ - switch (method) { - case CCL_DIST_MEAN: - return 'a'; - break; - case CCL_DIST_MEDIAN: - return 'm'; - break; - case CCL_DIST_SHORTEST: - return 's'; - break; - case CCL_DIST_LONGEST: - return 'x'; - break; - case CCL_DIST_AVG: - return 'v'; - break; - default: - break; - } - return '?'; - } -} - - -template -class FCCLKCluster { -protected: - const int nbPartitions; - const int nbElements; - const int nbDim; - const int nbPass; //< Number of call to EM algorithm - CCL::ClusterCenterMethod method; - CCL::Distance distance; - int* partitions; - -public: - FCCLKCluster(const int inNbPartitions, const int inNbElements, const FReal inDistMat[], const int inNbPass = 0) - : nbPartitions(inNbPartitions), nbElements(inNbElements), nbDim(0), nbPass(inNbPass), method(CCL::CCL_CCM_DUMMY), distance(CCL::CCL_DIST_DUMMY), partitions(nullptr) { - - double** distMatPtrs = new double*[nbElements]; - - // Build mask, everyone is here - for(int idxRow = 0 ; idxRow < nbElements ; ++idxRow){ - distMatPtrs[idxRow] = new double[idxRow+1]; - for(int idxCol = 0 ; idxCol <= idxRow ; ++idxCol){ - distMatPtrs[idxRow][idxCol] = double(inDistMat[idxCol*nbElements + idxRow]); - } - } - - // allocate partitions - partitions = new int[nbElements]; - - // Errors - double* error = new double[nbElements]; - // Nb of times the optimal clustering was found - int* ifound = new int[nbElements]; - - kmedoids (nbPartitions, nbElements, distMatPtrs, nbPass, partitions, error, ifound); - - for(int idxRow = 0 ; idxRow < nbElements ; ++idxRow){ - delete[] distMatPtrs[idxRow]; - } - delete[] distMatPtrs; - - } - - FCCLKCluster(const int inNbPartitions, const int inNbElements, const int inNbDim, const FReal inDataMat[], const CCL::ClusterCenterMethod inMethod, const CCL::Distance inDistance, const int inNbPass = 0) - : nbPartitions(inNbPartitions), nbElements(inNbElements), nbDim(inNbDim), nbPass(inNbPass), method(inMethod), distance(inDistance), partitions(nullptr) { - - double** dataMatPtrs = new double*[nbElements]; - int** mask = new int*[nbElements]; - - // Build mask, everyone is here - for(int idxRow = 0 ; idxRow < nbElements ; ++idxRow){ - mask[idxRow] = new int[idxRow+1]; - dataMatPtrs[idxRow] = new double[nbDim]; - for(int idxCol = 0 ; idxCol < nbDim ; ++idxCol){ - mask[idxRow][idxCol] = 1; - dataMatPtrs[idxRow][idxCol] = double(inDataMat[idxCol*nbElements + idxRow]); - } - } - - // allocate partitions - partitions = new int[nbElements]; - - // Errors - double* error = new double[nbElements]; - // Nb of times the optimal clustering was found - int* ifound = new int[nbElements]; - - // Weights - double* weights = new double[nbElements]; - for(int idxRow = 0 ; idxRow < nbElements ; ++idxRow) - weights[idxRow]=double(1.0); - - kcluster(nbPartitions, nbElements, nbDim, dataMatPtrs, mask, weights, 0, nbPass, ClusterCenterMethodToChar(method), DistanceToChar(distance), partitions, error, ifound); - - for(int idxRow = 0 ; idxRow < nbElements ; ++idxRow){ - delete[] mask[idxRow]; - delete[] dataMatPtrs[idxRow]; - } - delete[] mask; - delete[] dataMatPtrs; - - } - - ~FCCLKCluster(){ - delete[] partitions; - } - - int getPartitions(const int inNbPartitions, int inNbIdxInPartitions[]) const{ - - /// Map partitions to 0.. nbPartitions - FAssertLF(inNbPartitions == nbPartitions); - - // Copy partitions - int* sortedPartitions = new int[nbElements]; - for(int idx = 0 ; idx < nbElements ; ++idx){ - sortedPartitions[idx]=partitions[idx]; - } - // sort partitions - std::sort(sortedPartitions,sortedPartitions+nbElements); - - // Map partitions to 0..nbPartitions - int counterPartition=0; - int* mapPartitions = new int[inNbPartitions]; - int currentPartition=sortedPartitions[0]; - for(int idx = 0 ; idx < nbElements ; ++idx){ - mapPartitions[counterPartition]=currentPartition; - if(sortedPartitions[idx+1]!=currentPartition){ - currentPartition=sortedPartitions[idx+1]; - ++counterPartition; - } - } - FAssertLF(counterPartition == inNbPartitions); - - /// Count particles in each partition - int totalGiven = 0; - for(int idxPartition = 0 ; idxPartition < inNbPartitions ; ++idxPartition){ - - inNbIdxInPartitions[idxPartition]=0; - - for(int idx = 0 ; idx < nbElements ; ++idx){ - - if(partitions[idx]==mapPartitions[idxPartition]) - inNbIdxInPartitions[idxPartition]+=1; - - } - totalGiven +=inNbIdxInPartitions[idxPartition]; - } - FAssertLF(totalGiven == nbElements); - - return 0; // no empty partition in kclusters/kmedoids algorithms - } - - -}; - -#endif // FCCLKCLUSTER_HPP - diff --git a/Addons/HMat/Src/Clustering/FCCLTreeCluster.hpp b/Addons/HMat/Src/Clustering/FCCLTreeCluster.hpp deleted file mode 100644 index 246058aaeccb061e3112defbdee0de19ab299887..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Clustering/FCCLTreeCluster.hpp +++ /dev/null @@ -1,192 +0,0 @@ -// @SCALFMM_PRIVATE - -#ifndef FCCLTREECLUSTER_HPP -#define FCCLTREECLUSTER_HPP - -#include "./Utils/FGlobal.hpp" -#include "./Utils/FAssert.hpp" -#include "./Utils/FMath.hpp" -#include "../Utils/FHUtils.hpp" - -#include "FClusterTree.hpp" - -#include -#include -#include -#include -#include - -extern "C" { -#include -} - - -namespace CCL { - enum TreeMethod { - CCL_TM_SINGLE, - CCL_TM_MAXIMUM, - CCL_TM_AVG_LINKAGE - }; - - inline char TreeMethodToChar(const TreeMethod method){ - switch (method) { - case CCL_TM_SINGLE: - return 's'; - break; - case CCL_TM_MAXIMUM: - return 'm'; - break; - case CCL_TM_AVG_LINKAGE: - return 'a'; - break; - default: - break; - } - return '?'; - } - - - enum Distance { - CCL_DIST_MEAN, - CCL_DIST_MEDIAN, - CCL_DIST_SHORTEST, - CCL_DIST_LONGEST, - CCL_DIST_AVG - }; - - inline char DistanceToChar(const Distance method){ - switch (method) { - case CCL_DIST_MEAN: - return 'a'; - break; - case CCL_DIST_MEDIAN: - return 'm'; - break; - case CCL_DIST_SHORTEST: - return 's'; - break; - case CCL_DIST_LONGEST: - return 'x'; - break; - case CCL_DIST_AVG: - return 'v'; - break; - default: - break; - } - return '?'; - } -} - - -template -class FCCLTreeCluster { -protected: - const int dim; - CCL::TreeMethod method; - Node* croot; - -public: - FCCLTreeCluster(const int inDim, const FReal inDistMat[], const CCL::TreeMethod inMethod) - : dim(inDim), method(inMethod), croot(nullptr){ - - double** distMatPtrs = new double*[dim]; - int** mask = new int*[dim]; - - // Build mask, everyone is here - for(int idxRow = 0 ; idxRow < dim ; ++idxRow){ - mask[idxRow] = new int[idxRow+1]; - distMatPtrs[idxRow] = new double[idxRow+1]; - for(int idxCol = 0 ; idxCol <= idxRow ; ++idxCol){ - mask[idxRow][idxCol] = 1; - distMatPtrs[idxRow][idxCol] = double(inDistMat[idxCol*dim + idxRow]); - } - } - - croot = treecluster (dim, dim, nullptr, mask, nullptr, 0, '?', TreeMethodToChar(method), distMatPtrs); - FAssertLF(croot); - - for(int idxRow = 0 ; idxRow < dim ; ++idxRow){ - delete[] mask[idxRow]; - delete[] distMatPtrs[idxRow]; - } - delete[] mask; - delete[] distMatPtrs; - } - - ~FCCLTreeCluster(){ - free(croot); - } - - void fillClusterTree(FClusterTree* ctree) const { - int* permsOrigToNew = new int[dim]; - int* permsNewToOrig = new int[dim]; - - { - std::stack depthFirst; - depthFirst.push(croot[dim-2].right); - depthFirst.push(croot[dim-2].left); - - int idxPerm = 0; - while(depthFirst.size()){ - const int current = depthFirst.top(); - depthFirst.pop(); - if(0 <= current){ - permsOrigToNew[current] = idxPerm; - permsNewToOrig[idxPerm] = current; - idxPerm += 1; - } - else{ - depthFirst.push(croot[-1-current].right); - depthFirst.push(croot[-1-current].left); - } - } - } - - typename FClusterTree::Leaf* leaves = new typename FClusterTree::Leaf[dim]; - { - for(int idxUnk = 0 ; idxUnk < dim ; ++idxUnk){ - leaves[idxUnk].id = idxUnk; - leaves[idxUnk].offset= idxUnk; - leaves[idxUnk].size = 1; - } - } - - typename FClusterTree::Node* clusters = new typename FClusterTree::Node[dim-1]; - - for(int idxCluster = 0 ; idxCluster < dim-1 ; ++idxCluster){ - typename FClusterTree::Node& currentNd = clusters[idxCluster]; - const Node& srcNd = croot[idxCluster]; - currentNd.id = (-idxCluster)-1; - currentNd.size = 0; - currentNd.left = srcNd.left; - if(0 <= srcNd.left){ - currentNd.size += 1; - leaves[srcNd.left].parent = currentNd.id; - } - else{ - currentNd.size += clusters[(-srcNd.left)-1].size; - clusters[(-srcNd.left)-1].parent = currentNd.id; - } - currentNd.right = srcNd.right; - if(0 <= srcNd.right){ - currentNd.size += 1; - leaves[srcNd.right].parent = currentNd.id; - } - else{ - currentNd.size += clusters[(-srcNd.right)-1].size; - clusters[(-srcNd.right)-1].parent = currentNd.id; - } - currentNd.score = srcNd.distance; - } - clusters[dim-2].parent = 0; - - ctree->setData(dim, dim-1, clusters, dim, leaves, permsOrigToNew, permsNewToOrig); - // We do not deallocate, ctree is in charge of this - } - - -}; - -#endif // FCCLTREECLUSTER_HPP - diff --git a/Addons/HMat/Src/Clustering/FClusterTree.hpp b/Addons/HMat/Src/Clustering/FClusterTree.hpp deleted file mode 100644 index cfd4927eebf0640c6ade841579c1feb5d851f595..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Clustering/FClusterTree.hpp +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef FCLUSTERTREE_HPP -#define FCLUSTERTREE_HPP - -// @SCALFMM_PRIVATE -#include "./Utils/FGlobal.hpp" -#include "./Containers/FBoolArray.hpp" -#include "./Utils/FAssert.hpp" - -#include -#include - -template -class FClusterTree { -public: - struct Node { - int id; - int left; - int right; - int parent; - int size; - FReal score; - }; - - struct Leaf { - int id; - int parent; - int size; - int offset; - }; - -protected: - - FClusterTree(const FClusterTree&) = delete; - FClusterTree& operator=(const FClusterTree&) = delete; - - int dim; - int nbClusters; - const Node* clusters; - int nbLeaves; - const Leaf* leaves; - const int* permsOrigToNew; - const int* permsNewToOrig; - - void release(){ - dim = 0; - nbClusters = 0; - nbLeaves = 0; - delete[] clusters; - delete[] leaves; - delete[] permsOrigToNew; - delete[] permsNewToOrig; - } - -public: - FClusterTree() - : dim(0), nbClusters(0), clusters(nullptr), nbLeaves(0), leaves(nullptr), - permsOrigToNew(nullptr), permsNewToOrig(nullptr) { - - } - - ~FClusterTree(){ - release(); - } - - bool isInit() const { - return clusters != nullptr && leaves != nullptr; - } - - void setData(const int inDim, - const int inNbClusters, const Node* inClusters, - const int inNbLeaves, const Leaf* inLeaves, - const int* inPermsOrigToNew, const int* inPermsNewToOrig){ - release(); - dim = inDim; - nbClusters = inNbClusters; - clusters = inClusters; - nbLeaves = inNbLeaves; - leaves = inLeaves; - permsOrigToNew = inPermsOrigToNew; - permsNewToOrig = inPermsNewToOrig; - } - - void checkData() const{ - { // test permutations - for(int idx = 0 ; idx < dim ; ++idx){ - FAssertLF(permsNewToOrig[permsOrigToNew[idx]] == idx); - } - } - FAssertLF(clusters[nbClusters-1].size == dim); - { - FBoolArray unkTests(dim); - FAssertLF(nbClusters < dim); - for(int idx = 0 ; idx < nbClusters ; ++idx){ - const Node& nd = clusters[idx]; - FAssertLF(nd.id == (-idx)-1); - FAssertLF(0 <= nd.size); - FAssertLF(-nbClusters-1 < nd.left && nd.left < nbLeaves); - FAssertLF(-nbClusters-1 < nd.right && nd.right < nbLeaves); - - int size = 0; - if(0 <= nd.left){ - const Leaf& lf = leaves[nd.left]; - size += lf.size; - FAssertLF(nd.id == lf.parent); - FAssertLF(lf.size + lf.offset <= dim); - for(int idxUnk = 0 ; idxUnk < lf.size ; ++idxUnk){ - FAssertLF(unkTests.get(idxUnk + lf.offset) == false); - unkTests.set(idxUnk + lf.offset, true); - } - } - else{ - FAssertLF(nd.left < idx); - size += clusters[(-nd.left)-1].size; - FAssertLF(nd.id == clusters[(-nd.left)-1].parent); - } - if(0 <= nd.right){ - const Leaf& lf = leaves[nd.right]; - size += lf.size; - FAssertLF(nd.id == lf.parent); - FAssertLF(lf.size + lf.offset <= dim); - for(int idxUnk = 0 ; idxUnk < lf.size ; ++idxUnk){ - FAssertLF(unkTests.get(idxUnk + lf.offset) == false); - unkTests.set(idxUnk + lf.offset, true); - } - } - else{ - FAssertLF(nd.right < idx); - size += clusters[(-nd.right)-1].size; - FAssertLF(nd.id == clusters[(-nd.right)-1].parent, - nd.id ,"==", clusters[(-nd.right)-1].parent); - } - FAssertLF(size == nd.size); - } - - for(int idxUnk = 0 ; idxUnk < dim ; ++idxUnk){ - FAssertLF(unkTests.get(idxUnk) == true); - } - } - { // test permutations - int offset = 0; - for(int idx = 0 ; idx < nbLeaves ; ++idx){ - FAssertLF(leaves[idx].id == idx); - FAssertLF((clusters[-1-leaves[idx].parent].left == idx) - ^ (clusters[-1-leaves[idx].parent].right == idx)); - FAssertLF(leaves[idx].offset == offset); - offset += leaves[idx].size; - } - FAssertLF(dim == offset); - } - } - - void fillPermutations(int* inPermuts, int* invPermuts = nullptr) const { - memcpy(inPermuts, permsOrigToNew, sizeof(int)*dim); - if(invPermuts){ - memcpy(invPermuts, permsNewToOrig, sizeof(int)*dim); - } - } - - int getPartitions(const int inHeight, const int inNbPartitions, int inNbIdxInPartitions[]) const{ - // Here we select the inNbPartitions last partitions - // But we have to take them in the right order (left to right) - // To ensure coherency with the permutations - // if inNbPartitions, we should have inNbIdxInPartitions filled with 1 - FAssertLF(FMath::pow2(inHeight-1) == inNbPartitions); - - const int noNodeFlag = std::numeric_limits::max(); - std::queue breadthFirst; - breadthFirst.push(clusters[dim-2].left); - breadthFirst.push(clusters[dim-2].right); - - for(int idxLevel = 1 ; idxLevel < inHeight-1 ; ++idxLevel){ - std::queue breadthFirstLower; - - while(breadthFirst.size()){ - const int current = breadthFirst.front(); - breadthFirst.pop(); - - if(current == noNodeFlag){ - breadthFirstLower.push(noNodeFlag); - breadthFirstLower.push(noNodeFlag); - } - else if(0 <= current){ - breadthFirstLower.push(current); - breadthFirstLower.push(noNodeFlag); - } - else{ - breadthFirstLower.push(clusters[(-current)-1].left); - breadthFirstLower.push(clusters[(-current)-1].right); - } - } - - breadthFirst = std::move(breadthFirstLower); - } - FAssertLF(int(breadthFirst.size()) == inNbPartitions); - - int counterPartition = 0; - int totalGiven = 0; - int emptyPartitions = 0; - while(breadthFirst.size()){ - const int current = breadthFirst.front(); - breadthFirst.pop(); - - if(current == noNodeFlag){ - inNbIdxInPartitions[counterPartition] = 0; - emptyPartitions += 1; - } - else if(0 <= current){ - inNbIdxInPartitions[counterPartition] = leaves[current].size; - } - else{ - inNbIdxInPartitions[counterPartition] = clusters[(-current)-1].size; - } - totalGiven +=inNbIdxInPartitions[counterPartition]; - counterPartition += 1; - } - FAssertLF(totalGiven == dim); - - return emptyPartitions; - } - - - void saveToXml(const char inDirname[], const char inFilename[]) const{ - char buffer[1024]; - sprintf(buffer, "%s/%s", inDirname, inFilename); - saveToXml(buffer); - } - - void saveToXml(const char inFilename[]) const{ - FILE* fxml = fopen(inFilename, "w"); - FAssertLF(fxml); - - fprintf(fxml,"\n"); - fprintf(fxml,"\n"); - - for(int idxCluster = 0 ; idxCluster < nbClusters ; ++idxCluster){ - fprintf(fxml,"\t\n", clusters[idxCluster].id); - fprintf(fxml,"\t\t%d\n", clusters[idxCluster].size); - fprintf(fxml,"\t\t%e\n", clusters[idxCluster].score); - fprintf(fxml,"\t\t\n", clusters[idxCluster].left); - fprintf(fxml,"\t\t\n", clusters[idxCluster].right); - fprintf(fxml,"\t;\n"); - } - - for(int idxUnk = 0 ; idxUnk < nbLeaves ; ++idxUnk){ - fprintf(fxml,"\t\n", idxUnk); - fprintf(fxml,"\t\t%d\n", leaves[idxUnk].size); - fprintf(fxml,"\t\t%d\n", leaves[idxUnk].offset); - fprintf(fxml,"\t\t\n"); - for(int idxIndex = 0 ; idxIndex < leaves[idxUnk].size ; ++idxIndex){ - fprintf(fxml,"%d\n", permsNewToOrig[leaves[idxUnk].offset + idxIndex]); - } - fprintf(fxml,"\t\t\n"); - fprintf(fxml,"\t;\n"); - } - - fprintf(fxml,"\n"); - fclose(fxml); - } - - void saveToDot(const char inDirname[], const char inFilename[]) const{ - char buffer[1024]; - sprintf(buffer, "%s/%s", inDirname, inFilename); - saveToDot(buffer); - } - - void saveToDot(const char inFilename[]) const{ - FILE* fdot = fopen(inFilename, "w"); - FAssertLF(fdot); - - fprintf(fdot,"# dot -Tsvg %s -o %s.svg\n", - inFilename, inFilename); - fprintf(fdot,"digraph BST {\n"); - - for(int idxCluster = 0 ; idxCluster < nbClusters ; ++idxCluster){ - FAssertLF(idxCluster == -(clusters[idxCluster].id+1)); - fprintf(fdot,"\t %d [label=\"%d Size=%d\", tooltip=\"score %e\"];\n", - idxCluster, idxCluster, clusters[idxCluster].size, clusters[idxCluster].score); - fprintf(fdot,"\t %d -> %d;\n", idxCluster, (-clusters[idxCluster].left)-2+dim); - fprintf(fdot,"\t %d -> %d;\n", idxCluster, (-clusters[idxCluster].right)-2+dim); - } - - for(int idxUnk = 0 ; idxUnk < nbLeaves ; ++idxUnk){ - fprintf(fdot,"\t%d [label=\"%d size = %d offset = %d\"];\n", - idxUnk+dim-2, idxUnk, leaves[idxUnk].size, leaves[idxUnk].offset); - } - - fprintf(fdot,"}\n"); - fclose(fdot); - } -}; - - -#endif // FCLUSTERTREE_HPP - diff --git a/Addons/HMat/Src/Clustering/FConnexClustering.hpp b/Addons/HMat/Src/Clustering/FConnexClustering.hpp deleted file mode 100644 index 0810206c2a51d2d76c4b87b90984e9df52d1362c..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Clustering/FConnexClustering.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef FCONNEXCLUSTERING_HPP -#define FCONNEXCLUSTERING_HPP - -// @SCALFMM_PRIVATE - -#include "./Utils/FGlobal.hpp" -#include "./Utils/FAssert.hpp" -#include "./Utils/FMath.hpp" -#include "./Containers/FBoolArray.hpp" - -#include "FClusterTree.hpp" - -#include -#include -#include -#include -#include -#include - - - -template -class FConnexClustering { -protected: - const int dim; - - int* permsNewToOrig; - int* permsOrigToNew; - int* partitions; - int* partitionsOffset; - int nbPartitions; - -public: - FConnexClustering(const int inDim, const FReal inDistMat[], const FReal thresh) - : dim(inDim), - permsNewToOrig(new int[dim]), - permsOrigToNew(new int[dim]), - partitions(new int[dim]), - partitionsOffset(new int[dim+1]), - nbPartitions (0){ - - std::unique_ptr partitionsMappin(new int[dim]); - - for(int idx = 0 ; idx < dim ; ++idx){ - partitionsMappin[idx] = -1; - } - - partitionsOffset[0] = 0; - partitions[0] = 0; - - for(int idx = 0 ; idx < dim ; ++idx){ - if(partitionsMappin[idx] == -1){ - FAssertLF(nbPartitions < dim); - - partitionsOffset[nbPartitions+1] = partitionsOffset[nbPartitions]+1; - partitionsMappin[idx] = nbPartitions; - - int idxPartitionElement = partitionsOffset[nbPartitions]; - permsNewToOrig[idxPartitionElement] = idx; - - while(idxPartitionElement < partitionsOffset[nbPartitions+1]){ - FAssertLF(idxPartitionElement < dim); - - for(int idxOther = 0 ; idxOther < dim ; ++idxOther){ - if(partitionsMappin[idxOther] == -1 - && inDistMat[permsNewToOrig[idxPartitionElement]*dim + idxOther] < thresh){ - partitionsMappin[idxOther] = nbPartitions; - permsNewToOrig[partitionsOffset[nbPartitions+1]] = idxOther; - permsOrigToNew[idxOther] = partitionsOffset[nbPartitions+1]; - partitionsOffset[nbPartitions+1] += 1; - FAssertLF(partitionsOffset[nbPartitions+1] <= dim); - } - } - - idxPartitionElement += 1; - } - - partitions[nbPartitions] = partitionsOffset[nbPartitions+1]-partitionsOffset[nbPartitions]; - nbPartitions += 1; - } - } - - FAssertLF(partitionsOffset[nbPartitions] == dim); - } - - ~FConnexClustering(){ - delete[] permsNewToOrig; - delete[] permsOrigToNew; - delete[] partitionsOffset; - delete[] partitions; - } - - - void fillPermutations(int* inPermuts, int* invPermuts = nullptr) const { - memcpy(inPermuts, permsOrigToNew, sizeof(int)*dim); - if(invPermuts){ - memcpy(invPermuts, permsNewToOrig, sizeof(int)*dim); - } - } - - int getNbPartitions() const{ - return nbPartitions; - } - - void getPartitions(const int inNbPartitions, int inNbIdxInPartitions[]) const{ - FAssertLF(nbPartitions == inNbPartitions); - memcpy(inNbIdxInPartitions, partitions, sizeof(int)*nbPartitions); - } -}; - -#endif // FCONNEXCLUSTERING_HPP - diff --git a/Addons/HMat/Src/Clustering/FGraphThreshold.hpp b/Addons/HMat/Src/Clustering/FGraphThreshold.hpp deleted file mode 100644 index daae34224f949eb17b0f35bd7b9c621c23c7f76f..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Clustering/FGraphThreshold.hpp +++ /dev/null @@ -1,301 +0,0 @@ -#ifndef FGRAPHTHRESHOLD_HPP -#define FGRAPHTHRESHOLD_HPP - -// @SCALFMM_PRIVATE - -#include "./Utils/FGlobal.hpp" -#include "./Utils/FAssert.hpp" -#include "./Utils/FMath.hpp" -#include "./Containers/FBoolArray.hpp" - -#include "FClusterTree.hpp" - -#include -#include -#include -#include -#include -#include - -#include - -template -class FGraphThreshold { -protected: - const int dim; - const FReal treshold; - - int* permutations; - std::pair* gclusters; - -public: - static FReal GetDefaultRadius(const int inDim, const FReal inDistMat[]){ - FReal avg = 0; - FReal min = std::numeric_limits::max(); - const FReal dimSquare = FReal(inDim*inDim); - for(int idxCol = 0 ; idxCol < inDim ; ++idxCol){ - for(int idxRow = 0 ; idxRow < inDim ; ++idxRow){ - avg += (inDistMat[idxCol*inDim + idxRow]/dimSquare); - min = (min < inDistMat[idxCol*inDim + idxRow]? min:inDistMat[idxCol*inDim + idxRow]); - } - } - return (avg+min) / FReal(2); - } - - FGraphThreshold(const int inDim, const FReal inDistMat[], const FReal inTreshold) - : dim(inDim), treshold(inTreshold), - permutations(new int[dim]), - gclusters (new std::pair[dim-1]){ - - for(int idx = 0 ; idx < dim ; ++idx){ - permutations[idx] = idx; - } - - std::queue> intervals; - intervals.push(std::pair(0, dim)); - - int idxCluster = dim-2; - int idxChildCluster = dim-3; - int countToUnknowns = 0; - - while(intervals.size()){ - FAssertLF(idxCluster >= 0); - - const std::pair currentCluster = intervals.front(); - intervals.pop(); - - const int sizeInterval = currentCluster.second-currentCluster.first; - FAssertLF(sizeInterval != 1); - - int nbValuesUnderThreshold = 0; - for(int idxCol = 0 ; idxCol < sizeInterval ; ++idxCol){ - const int idxColReal = permutations[idxCol+currentCluster.first]; - for(int idxRow = 0 ; idxRow < sizeInterval ; ++idxRow){ - const int idxRowReal = permutations[idxRow+currentCluster.first]; - nbValuesUnderThreshold += (inDistMat[idxColReal*dim+ idxRowReal] < treshold && idxRowReal != idxColReal? 1 : 0); - } - } - if(nbValuesUnderThreshold != 0){ - // Base value for all array indexings - const SCOTCH_Num baseval = 0; - // Number of vertices in graph - const SCOTCH_Num vertnbr = sizeInterval; - // Number of arcs in graph. Since edges are represented by both of their ends, - // the number of edge data in the graph is twice the number of graph edges. - const SCOTCH_Num edgenbr = nbValuesUnderThreshold;// it is already symmetric - // Array of start indices in edgetab of vertex adjacency sub-arrays - SCOTCH_Num* verttab = new SCOTCH_Num[vertnbr+1]; - SCOTCH_Num* vendtab = &verttab[1]; - // edgetab[verttab[i]] to edgetab[vendtab[i] − 1] - SCOTCH_Num* edgetab = new SCOTCH_Num[edgenbr]; - // Optional array, of size vertnbr, holding the integer load associated with every vertex. - SCOTCH_Num* velotab = nullptr; - // Optional array, of a size equal at least to (max i (vendtab[i]) − baseval), holding the integer load associated with every arc. - SCOTCH_Num* edlotab = nullptr; - SCOTCH_Num* vlbltab = nullptr; - - verttab[0] = 0; - for(int idxCol = 0 ; idxCol < sizeInterval ; ++idxCol){ - const int idxColReal = permutations[idxCol+currentCluster.first]; - verttab[idxCol+1] = verttab[idxCol]; - for(int idxRow = 0 ; idxRow < sizeInterval ; ++idxRow){ - const int idxRowReal = permutations[idxRow+currentCluster.first]; - if(inDistMat[idxColReal*dim+ idxRowReal] < treshold - && idxColReal != idxRowReal){ - edgetab[verttab[idxCol+1]] = idxRow; - verttab[idxCol+1] += 1; - } - } - } - FAssertLF(verttab[vertnbr] == edgenbr); - - SCOTCH_Graph grafdat; - FAssertLF(SCOTCH_graphInit(&grafdat) == 0); - - FAssertLF(SCOTCH_graphBuild(&grafdat, baseval, vertnbr, verttab, vendtab, - velotab, vlbltab, edgenbr, edgetab, edlotab) == 0); - FAssertLF(SCOTCH_graphCheck(&grafdat) == 0); - - SCOTCH_Strat straptr; - FAssertLF(SCOTCH_stratInit(&straptr) == 0); - - - //const SCOTCH_Num pwgtmax = std::numeric_limits::max(); //maximum cluster vertex weight - //const double densmin = 0; // the minimum edge density - //const double bbalval = 0.2;// bipartition imbalance ratio - //SCOTCH_stratGraphClusterBuild (&straptr, SCOTCH_STRATDEFAULT, pwgtmax, densmin, bbalval); - - const int partnbr = 2; - SCOTCH_Num* parttab = new SCOTCH_Num[vertnbr]; - FAssertLF(SCOTCH_graphPart(&grafdat, partnbr, &straptr, parttab) == 0); - - { - int idxLeft = 0; - int idxRight = sizeInterval-1; - while(idxLeft <= idxRight){ - if(parttab[idxLeft] == 0){ - idxLeft += 1; - } - else if(parttab[idxRight] == 1){ - idxRight -= 1; - } - else{ - const int unk = parttab[idxLeft]; - parttab[idxLeft] = parttab[idxRight]; - parttab[idxRight] = unk; - - const int unkPerm = permutations[idxLeft+currentCluster.first]; - permutations[idxLeft+currentCluster.first] = permutations[idxRight+currentCluster.first]; - permutations[idxRight+currentCluster.first] = unkPerm; - - idxLeft += 1; - idxRight -= 1; - } - } - // idxLeft is on the first 1 - if(idxLeft == 1){ - gclusters[idxCluster].first = permutations[currentCluster.first]; - countToUnknowns += 1; - FAssertLF(countToUnknowns <= dim); - } - else if(idxLeft > 1){ - FAssertLF(idxChildCluster >= 0); - gclusters[idxCluster].first = (-idxChildCluster)-1; - idxChildCluster -= 1; - intervals.push(std::pair(currentCluster.first, currentCluster.first+idxLeft)); - } - if(idxRight == sizeInterval-2){ - gclusters[idxCluster].second = permutations[sizeInterval-1+currentCluster.first]; - countToUnknowns += 1; - FAssertLF(countToUnknowns <= dim); - } - else if(idxRight < sizeInterval-2){ - FAssertLF(idxChildCluster >= 0); - gclusters[idxCluster].second = (-idxChildCluster)-1; - idxChildCluster -= 1; - intervals.push(std::pair(currentCluster.first+idxLeft, currentCluster.first+sizeInterval)); - } - } - - SCOTCH_stratExit(&straptr); - SCOTCH_graphExit(&grafdat); - - delete[] parttab; - delete[] verttab; - delete[] edgetab; - } - else{ - int idxLeft = sizeInterval/2; - int idxRight = idxLeft-1; - // idxLeft is on the first 1 - if(idxLeft == 1){ - gclusters[idxCluster].first = permutations[currentCluster.first]; - countToUnknowns += 1; - FAssertLF(countToUnknowns <= dim); - } - else if(idxLeft > 1){ - FAssertLF(idxChildCluster >= 0); - gclusters[idxCluster].first = (-idxChildCluster)-1; - idxChildCluster -= 1; - intervals.push(std::pair(currentCluster.first, currentCluster.first+idxLeft)); - } - if(idxRight == sizeInterval-2){ - gclusters[idxCluster].second = permutations[sizeInterval-1+currentCluster.first]; - countToUnknowns += 1; - FAssertLF(countToUnknowns <= dim); - } - else if(idxRight < sizeInterval-2){ - FAssertLF(idxChildCluster >= 0); - gclusters[idxCluster].second = (-idxChildCluster)-1; - idxChildCluster -= 1; - intervals.push(std::pair(currentCluster.first+idxLeft, currentCluster.first+sizeInterval)); - } - } - - idxCluster -= 1; - } - FAssertLF(idxCluster == -1); - FAssertLF(idxChildCluster == -1); - FAssertLF(countToUnknowns == dim); - } - - ~FGraphThreshold(){ - delete[] permutations; - delete[] gclusters; - } - - void fillClusterTree(FClusterTree* ctree) const { - int* permsOrigToNew = new int[dim]; - int* permsNewToOrig = new int[dim]; - - { - std::stack depthFirst; - depthFirst.push(gclusters[dim-2].second); - depthFirst.push(gclusters[dim-2].first); - - int idxPerm = 0; - while(depthFirst.size()){ - const int current = depthFirst.top(); - depthFirst.pop(); - if(0 <= current){ - permsOrigToNew[current] = idxPerm; - permsNewToOrig[idxPerm] = current; - FAssertLF(permsNewToOrig[idxPerm] == permutations[idxPerm]); - idxPerm += 1; - } - else{ - depthFirst.push(gclusters[-1-current].second); - depthFirst.push(gclusters[-1-current].first); - } - } - } - - typename FClusterTree::Leaf* leaves = new typename FClusterTree::Leaf[dim]; - { - for(int idxUnk = 0 ; idxUnk < dim ; ++idxUnk){ - leaves[idxUnk].id = idxUnk; - leaves[idxUnk].offset= idxUnk; - leaves[idxUnk].size = 1; - } - } - - typename FClusterTree::Node* clusters = new typename FClusterTree::Node[dim-1]; - - for(int idxCluster = 0 ; idxCluster < dim-1 ; ++idxCluster){ - typename FClusterTree::Node& currentNd = clusters[idxCluster]; - const std::pair& srcNd = gclusters[idxCluster]; - currentNd.id = (-idxCluster)-1; - currentNd.size = 0; - currentNd.left = srcNd.first; - if(0 <= srcNd.first){ - currentNd.size += 1; - leaves[srcNd.first].parent = currentNd.id; - } - else{ - currentNd.size += clusters[(-srcNd.first)-1].size; - clusters[(-srcNd.first)-1].parent = currentNd.id; - } - currentNd.right = srcNd.second; - if(0 <= srcNd.second){ - currentNd.size += 1; - leaves[srcNd.second].parent = currentNd.id; - } - else{ - currentNd.size += clusters[(-srcNd.second)-1].size; - clusters[(-srcNd.second)-1].parent = currentNd.id; - } - currentNd.score = 0; - } - clusters[dim-2].parent = 0; - - ctree->setData(dim, dim-1, clusters, dim, leaves, permsOrigToNew, permsNewToOrig); - // We do not deallocate, ctree is in charge of this - } - - -}; - - - -#endif // FGRAPHTHRESHOLD_HPP - diff --git a/Addons/HMat/Src/Clustering/FMaxDistCut.hpp b/Addons/HMat/Src/Clustering/FMaxDistCut.hpp deleted file mode 100644 index 793d15f127d266d7fea988c4ac721bc449f6a3b3..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Clustering/FMaxDistCut.hpp +++ /dev/null @@ -1,203 +0,0 @@ -#ifndef FMAXDISTCUT_HPP -#define FMAXDISTCUT_HPP - -// @SCALFMM_PRIVATE - -#include "./Utils/FGlobal.hpp" -#include "./Utils/FAssert.hpp" -#include "./Utils/FMath.hpp" -#include "./Containers/FBoolArray.hpp" - -#include "FClusterTree.hpp" - -#include -#include -#include -#include -#include -#include - - - -template -class FMaxDistCut { -protected: - const int dim; - - int* permutations; - std::pair* gclusters; - -public: - FMaxDistCut(const int inDim, const FReal inDistMat[]) - : dim(inDim), - permutations(new int[dim]), - gclusters (new std::pair[dim-1]){ - - for(int idx = 0 ; idx < dim ; ++idx){ - permutations[idx] = idx; - } - - std::queue> intervals; - intervals.push(std::pair(0, dim)); - - int idxCluster = dim-2; - int idxChildCluster = dim-3; - int countToUnknowns = 0; - - while(intervals.size()){ - FAssertLF(idxCluster >= 0); - - const std::pair currentCluster = intervals.front(); - intervals.pop(); - - const int sizeInterval = currentCluster.second-currentCluster.first; - FAssertLF(sizeInterval != 1); - - int firstIdxMax = permutations[0 + currentCluster.first]; - int secondIdxMax = permutations[1 + currentCluster.first]; - for(int idxCol = 0 ; idxCol < sizeInterval ; ++idxCol){ - const int idxColReal = permutations[idxCol+currentCluster.first]; - for(int idxRow = idxCol+1 ; idxRow < sizeInterval ; ++idxRow){ - const int idxRowReal = permutations[idxRow+currentCluster.first]; - if(inDistMat[idxColReal*dim+ idxRowReal] - > inDistMat[firstIdxMax*dim + secondIdxMax]){ - firstIdxMax = idxColReal; - secondIdxMax = idxRowReal; - } - } - } - - { - int idxLeft = 0; - int idxRight = sizeInterval-1; - while(idxLeft <= idxRight){ - const int idxLeftReal = permutations[idxLeft + currentCluster.first]; - const int idxRightReal = permutations[idxRight + currentCluster.first]; - if(inDistMat[idxLeftReal*dim+ firstIdxMax] - < inDistMat[idxLeftReal*dim + secondIdxMax]){ - idxLeft += 1; - } - else if(inDistMat[idxRightReal*dim+ firstIdxMax] - >= inDistMat[idxRightReal*dim + secondIdxMax]){ - idxRight -= 1; - } - else{ - const int unkPerm = permutations[idxLeft+currentCluster.first]; - permutations[idxLeft+currentCluster.first] = permutations[idxRight+currentCluster.first]; - permutations[idxRight+currentCluster.first] = unkPerm; - - idxLeft += 1; - idxRight -= 1; - } - } - // idxLeft is on the first 1 - if(idxLeft == 1){ - gclusters[idxCluster].first = permutations[currentCluster.first]; - countToUnknowns += 1; - FAssertLF(countToUnknowns <= dim); - } - else if(idxLeft > 1){ - FAssertLF(idxChildCluster >= 0); - gclusters[idxCluster].first = (-idxChildCluster)-1; - idxChildCluster -= 1; - intervals.push(std::pair(currentCluster.first, currentCluster.first+idxLeft)); - } - if(idxRight == sizeInterval-2){ - gclusters[idxCluster].second = permutations[sizeInterval-1+currentCluster.first]; - countToUnknowns += 1; - FAssertLF(countToUnknowns <= dim); - } - else if(idxRight < sizeInterval-2){ - FAssertLF(idxChildCluster >= 0); - gclusters[idxCluster].second = (-idxChildCluster)-1; - idxChildCluster -= 1; - intervals.push(std::pair(currentCluster.first+idxLeft, currentCluster.first+sizeInterval)); - } - } - - idxCluster -= 1; - } - FAssertLF(idxCluster == -1); - FAssertLF(idxChildCluster == -1); - FAssertLF(countToUnknowns == dim); - } - - ~FMaxDistCut(){ - delete[] permutations; - delete[] gclusters; - } - - void fillClusterTree(FClusterTree* ctree) const { - int* permsOrigToNew = new int[dim]; - int* permsNewToOrig = new int[dim]; - - { - std::stack depthFirst; - depthFirst.push(gclusters[dim-2].second); - depthFirst.push(gclusters[dim-2].first); - - int idxPerm = 0; - while(depthFirst.size()){ - const int current = depthFirst.top(); - depthFirst.pop(); - if(0 <= current){ - permsOrigToNew[current] = idxPerm; - permsNewToOrig[idxPerm] = current; - FAssertLF(permsNewToOrig[idxPerm] == permutations[idxPerm]); - idxPerm += 1; - } - else{ - depthFirst.push(gclusters[-1-current].second); - depthFirst.push(gclusters[-1-current].first); - } - } - } - - typename FClusterTree::Leaf* leaves = new typename FClusterTree::Leaf[dim]; - { - for(int idxUnk = 0 ; idxUnk < dim ; ++idxUnk){ - leaves[idxUnk].id = idxUnk; - leaves[idxUnk].offset= idxUnk; - leaves[idxUnk].size = 1; - } - } - - typename FClusterTree::Node* clusters = new typename FClusterTree::Node[dim-1]; - - for(int idxCluster = 0 ; idxCluster < dim-1 ; ++idxCluster){ - typename FClusterTree::Node& currentNd = clusters[idxCluster]; - const std::pair& srcNd = gclusters[idxCluster]; - currentNd.id = (-idxCluster)-1; - currentNd.size = 0; - currentNd.left = srcNd.first; - if(0 <= srcNd.first){ - currentNd.size += 1; - leaves[srcNd.first].parent = currentNd.id; - } - else{ - currentNd.size += clusters[(-srcNd.first)-1].size; - clusters[(-srcNd.first)-1].parent = currentNd.id; - } - currentNd.right = srcNd.second; - if(0 <= srcNd.second){ - currentNd.size += 1; - leaves[srcNd.second].parent = currentNd.id; - } - else{ - currentNd.size += clusters[(-srcNd.second)-1].size; - clusters[(-srcNd.second)-1].parent = currentNd.id; - } - currentNd.score = 0; - } - clusters[dim-2].parent = 0; - - ctree->setData(dim, dim-1, clusters, dim, leaves, permsOrigToNew, permsNewToOrig); - // We do not deallocate, ctree is in charge of this - } - - -}; - - -#endif // FMAXDISTCUT_HPP - diff --git a/Addons/HMat/Src/Containers/FBlockPMapping.hpp b/Addons/HMat/Src/Containers/FBlockPMapping.hpp deleted file mode 100644 index 9f99da3bf989fe51b679a98863d963833ff8890e..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Containers/FBlockPMapping.hpp +++ /dev/null @@ -1,207 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FBLOCKPMAPPING_HPP -#define FBLOCKPMAPPING_HPP - - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" -#include "Utils/FMath.hpp" -#include "Utils/FAssert.hpp" - -#include "../Utils/FHUtils.hpp" - -#include -#include - - -template -class FBlockPMapping { -protected: - struct CellCNode { - FBlockDescriptor infos; - CellClass cell; - }; - - struct RowUNode { - FBlockDescriptor infos; - CellClass cell; - }; - - struct ColVNode { - FBlockDescriptor infos; - CellClass cell; - }; - - const int dim; - const int nbPartitions; - const int nbCells; - - CellCNode* cBlocks; - RowUNode* uRowBlocks; - ColVNode* vColBlocks; - - FBlockPMapping(const FBlockPMapping&) = delete; - FBlockPMapping& operator=(const FBlockPMapping&) = delete; - -public: - explicit FBlockPMapping(const int inDim, const int partitions[], const int inNbPartitions) - : dim(inDim), - nbPartitions(inNbPartitions), - nbCells(inNbPartitions*inNbPartitions), - cBlocks(nullptr){ - FAssertLF(nbPartitions <= inDim); - FAssertLF(1 <= nbPartitions); - - std::unique_ptr partitionsOffset(new int[nbPartitions]); - partitionsOffset[0] = 0; - for(int idxPart = 1 ; idxPart < nbPartitions ; ++idxPart){ - partitionsOffset[idxPart] = partitionsOffset[idxPart-1] + partitions[idxPart-1]; - } - - cBlocks = new CellCNode[nbCells]; - - for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.row = partitionsOffset[idxPartRow]; - cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.col = partitionsOffset[idxPartCol]; - cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.nbRows = partitions[idxPartRow]; - cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.nbCols = partitions[idxPartCol]; - cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.level = 0; - } - } - - uRowBlocks = new RowUNode[nbPartitions]; - for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - uRowBlocks[idxPartRow].infos.row = partitionsOffset[idxPartRow]; - uRowBlocks[idxPartRow].infos.col = 0; - uRowBlocks[idxPartRow].infos.nbRows = partitions[idxPartRow]; - uRowBlocks[idxPartRow].infos.nbCols = dim; - uRowBlocks[idxPartRow].infos.level = 0; - } - - vColBlocks = new ColVNode[nbPartitions]; - for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - vColBlocks[idxPartCol].infos.row = 0; - vColBlocks[idxPartCol].infos.col = partitionsOffset[idxPartCol]; - vColBlocks[idxPartCol].infos.nbRows = dim; - vColBlocks[idxPartCol].infos.nbCols = partitions[idxPartCol]; - vColBlocks[idxPartCol].infos.level = 0; - } - } - - ~FBlockPMapping(){ - delete[] cBlocks; - delete[] uRowBlocks; - delete[] vColBlocks; - } - - int getNbBlocks() const { - return nbCells; - } - - // Iterate blocks - - CellClass& getCBlock(const int idxRowPart, const int idxColPart){ - return cBlocks[idxColPart*nbPartitions + idxRowPart].cell; - } - - const CellClass& getCBlock(const int idxRowPart, const int idxColPart) const { - return cBlocks[idxColPart*nbPartitions + idxRowPart].cell; - } - - const FBlockDescriptor& getCBlockInfo(const int idxRowPart, const int idxColPart) const { - return cBlocks[idxColPart*nbPartitions + idxRowPart].infos; - } - - void forAllCBlocksDescriptor(std::function callback){ - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - callback(cBlocks[idxCell].infos); - } - } - - void forAllBlocks(std::function callback){ - for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - callback(cBlocks[idxPartCol*nbPartitions + idxPartRow].infos, - cBlocks[idxPartCol*nbPartitions + idxPartRow].cell, - uRowBlocks[idxPartRow].cell, - vColBlocks[idxPartCol].cell); - } - } - } - - // Iterate row blocks - - CellClass& getUBlock(const int idxRowPart){ - return uRowBlocks[idxRowPart].cell; - } - - const CellClass& getUBlock(const int idxRowPart) const { - return uRowBlocks[idxRowPart].cell; - } - - const FBlockDescriptor& getUBlockInfo(const int idxRowPart) const { - return uRowBlocks[idxRowPart].infos; - } - - - // Iterate col blocks - - CellClass& getVBlock(const int idxColPart){ - return vColBlocks[idxColPart].cell; - } - - const CellClass& getVBlock(const int idxColPart) const { - return vColBlocks[idxColPart].cell; - } - - const FBlockDescriptor& getVBlockInfo(const int idxColPart) const { - return vColBlocks[idxColPart].infos; - } - - // Operations - void gemv(FReal res[], const FReal vec[]) const { - for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ -// &res[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.row], -// &vec[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.col]) -// cBlocks[idxPartCol*nbPartitions + idxPartRow].cell, -// uRowBlocks[idxPartRow].cell, -// vColBlocks[idxPartCol].cell; - } - } - } - - void gemm(FReal res[], const FReal mat[], const int nbRhs) const { - for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ -// &res[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.row], -// &vec[cBlocks[idxPartCol*nbPartitions + idxPartRow].infos.col]) -// cBlocks[idxPartCol*nbPartitions + idxPartRow].cell, -// uRowBlocks[idxPartRow].cell, -// vColBlocks[idxPartCol].cell; -// nbRhs, dim - } - } - } -}; - -#endif // FBLOCKPMAPPING_HPP - - diff --git a/Addons/HMat/Src/Containers/FPartitionsMapping.hpp b/Addons/HMat/Src/Containers/FPartitionsMapping.hpp deleted file mode 100644 index f42a3e12d2b64a47f2519a437caf2aa1b6bb09f0..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Containers/FPartitionsMapping.hpp +++ /dev/null @@ -1,154 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FPARTITIONSMAPPING_HPP -#define FPARTITIONSMAPPING_HPP - - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" -#include "Utils/FMath.hpp" -#include "Utils/FAssert.hpp" - -#include "../Utils/FHUtils.hpp" - -#include -#include - - -template -class FPartitionsMapping { -protected: - struct CellNode { - FBlockDescriptor infos; - CellClass cell; - }; - - const int dim; - const int nbPartitions; - const int nbCells; - - CellNode* cells; - - FPartitionsMapping(const FPartitionsMapping&) = delete; - FPartitionsMapping& operator=(const FPartitionsMapping&) = delete; - -public: - explicit FPartitionsMapping(const int inDim, const int partitions[], const int inNbPartitions) - : dim(inDim), - nbPartitions(inNbPartitions), - nbCells(inNbPartitions*inNbPartitions), - cells(nullptr){ - FAssertLF(nbPartitions <= inDim); - FAssertLF(1 <= nbPartitions); - - std::unique_ptr partitionsOffset(new int[nbPartitions]); - partitionsOffset[0] = 0; - for(int idxPart = 1 ; idxPart < nbPartitions ; ++idxPart){ - partitionsOffset[idxPart] = partitionsOffset[idxPart-1] + partitions[idxPart-1]; - } - - cells = new CellNode[nbCells]; - - for(int idxPartCol = 0 ; idxPartCol < nbPartitions ; ++idxPartCol){ - for(int idxPartRow = 0 ; idxPartRow < nbPartitions ; ++idxPartRow){ - cells[idxPartCol*nbPartitions + idxPartRow].infos.row = partitionsOffset[idxPartRow]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.col = partitionsOffset[idxPartCol]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.nbRows = partitions[idxPartRow]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.nbCols = partitions[idxPartCol]; - cells[idxPartCol*nbPartitions + idxPartRow].infos.level = 0; - } - } - } - - ~FPartitionsMapping(){ - delete[] cells; - } - - int getNbBlocks() const { - return nbCells; - } - - CellClass& getCell(const int idxRowPart, const int idxColPart){ - return cells[idxColPart*nbPartitions + idxRowPart].cell; - } - - const CellClass& getCell(const int idxRowPart, const int idxColPart) const { - return cells[idxColPart*nbPartitions + idxRowPart].cell; - } - - const FBlockDescriptor& getCellInfo(const int idxRowPart, const int idxColPart) const { - return cells[idxColPart*nbPartitions + idxRowPart].infos; - } - - void forAllBlocksDescriptor(std::function callback){ - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - callback(cells[idxCell].infos); - } - } - - void forAllCellBlocks(std::function callback){ - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - callback(cells[idxCell].infos, - cells[idxCell].cell); - } - } - - - template - void fillBlocks(MatrixClass& matrix){ - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - cells[idxCell].cell.fill(matrix.getBlock( - cells[idxCell].infos.row, - cells[idxCell].infos.col, - cells[idxCell].infos.nbRows, - cells[idxCell].infos.nbCols - ), - cells[idxCell].infos.level); - } - } - - template - void fillBlocks(const MatrixClass& matrix){ - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - cells[idxCell].cell.fill(matrix.getBlock( - cells[idxCell].infos.row, - cells[idxCell].infos.col, - cells[idxCell].infos.nbRows, - cells[idxCell].infos.nbCols - ), - cells[idxCell].infos.level); - } - } - - void gemv(FReal res[], const FReal vec[]) const { - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - cells[idxCell].cell.gemv(&res[cells[idxCell].infos.row], - &vec[cells[idxCell].infos.col]); - } - } - - void gemm(FReal res[], const FReal mat[], const int nbRhs) const { - for(int idxCell = 0 ; idxCell < nbCells ; ++idxCell){ - cells[idxCell].cell.gemm(&res[cells[idxCell].infos.col], - &mat[cells[idxCell].infos.row], - nbRhs, dim); - } - } -}; - -#endif // FPARTITIONSMAPPING_HPP - diff --git a/Addons/HMat/Src/Containers/FStaticDiagonalBisection.hpp b/Addons/HMat/Src/Containers/FStaticDiagonalBisection.hpp deleted file mode 100644 index 5078ab78feb7b48a4fd630b970998fe072fd73f6..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Containers/FStaticDiagonalBisection.hpp +++ /dev/null @@ -1,336 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FSTATICDIAGONALBISECTION_HPP -#define FSTATICDIAGONALBISECTION_HPP - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" -#include "Utils/FMath.hpp" -#include "Utils/FAssert.hpp" - -#include "../Utils/FHUtils.hpp" - -#include -#include - - -template -class FStaticDiagonalBisection { -protected: - struct LeafNode { - FBlockDescriptor infos; - LeafClass leaf; - }; - - struct CellNode { - FBlockDescriptor infos; - CellClass cell; - }; - - const int dim; - const int height; - - int* nbCells; - CellNode** cells; - - int nbLeaves; - LeafNode* leaves; - - int totalNbBlocks; - - FStaticDiagonalBisection(const FStaticDiagonalBisection&) = delete; - FStaticDiagonalBisection& operator=(const FStaticDiagonalBisection&) = delete; - -public: - explicit FStaticDiagonalBisection(const int inDim, const int inHeight) - : dim(inDim), height(inHeight), - nbCells(0), cells(nullptr), - nbLeaves(0), leaves(nullptr), - totalNbBlocks(0){ - FAssertLF(FMath::pow2(height) <= inDim); - - cells = new CellNode*[height]; - FSetToZeros(cells, height); - nbCells = new int[height]; - FSetToZeros(nbCells, height); - - for(int idxLevel = 1 ; idxLevel < height-1 ; ++idxLevel){ - const int nbCellsAtLevel = FMath::pow2(idxLevel); - cells[idxLevel] = new CellNode[nbCellsAtLevel]; - nbCells[idxLevel] = nbCellsAtLevel; - totalNbBlocks += nbCellsAtLevel; - - const int nbCellsInDirection = nbCells[idxLevel]; - for(int idxCell = 0 ; idxCell < nbCellsAtLevel ; ++idxCell){ - const int rowCellNumber = (idxCell&1? idxCell-1 : idxCell+1); - const int colCellNumner = idxCell; - cells[idxLevel][idxCell].infos.row = ((rowCellNumber*dim)/nbCellsInDirection); - cells[idxLevel][idxCell].infos.col = ((colCellNumner*dim)/nbCellsInDirection); - cells[idxLevel][idxCell].infos.nbRows = (((rowCellNumber+1)*dim)/nbCellsInDirection) - - cells[idxLevel][idxCell].infos.row; - cells[idxLevel][idxCell].infos.nbCols =(((colCellNumner+1)*dim)/nbCellsInDirection) - - cells[idxLevel][idxCell].infos.col; - cells[idxLevel][idxCell].infos.level = idxLevel; - } - } - nbLeaves = FMath::pow2(height-1); - { - const int idxLevel = height-1; - const int nbCellsAtLevel = nbLeaves; - cells[idxLevel] = new CellNode[nbCellsAtLevel]; - nbCells[idxLevel] = nbCellsAtLevel; - totalNbBlocks += nbCellsAtLevel; - - const int nbLeavesInDirection = nbLeaves; - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - const int rowLeafNumber = (idxLeaf^1); - const int colLeafNumber = idxLeaf; - cells[idxLevel][idxLeaf].infos.row = ((rowLeafNumber*dim)/nbLeavesInDirection); - cells[idxLevel][idxLeaf].infos.col = ((colLeafNumber*dim)/nbLeavesInDirection); - cells[idxLevel][idxLeaf].infos.nbRows = (((rowLeafNumber+1)*dim)/nbLeavesInDirection) - - cells[idxLevel][idxLeaf].infos.row; - cells[idxLevel][idxLeaf].infos.nbCols = (((colLeafNumber+1)*dim)/nbLeavesInDirection) - - cells[idxLevel][idxLeaf].infos.col; - cells[idxLevel][idxLeaf].infos.level = height-1; - } - } - - leaves = new LeafNode[nbLeaves]; - totalNbBlocks += nbLeaves; - { - const int nbLeavesInDirection = nbLeaves; - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - const int rowLeafNumber = idxLeaf; - const int colLeafNumber = idxLeaf; - leaves[idxLeaf].infos.row = ((rowLeafNumber*dim)/nbLeavesInDirection); - leaves[idxLeaf].infos.col = ((colLeafNumber*dim)/nbLeavesInDirection); - leaves[idxLeaf].infos.nbRows = (((rowLeafNumber+1)*dim)/nbLeavesInDirection) - - leaves[idxLeaf].infos.row; - leaves[idxLeaf].infos.nbCols = (((colLeafNumber+1)*dim)/nbLeavesInDirection) - - leaves[idxLeaf].infos.col; - leaves[idxLeaf].infos.level = height; - } - } - } - - explicit FStaticDiagonalBisection(const int inDim, const int inHeight, - const int partitions[], const int nbPartitions) - : dim(inDim), height(inHeight), - nbCells(0), cells(nullptr), - nbLeaves(0), leaves(nullptr), - totalNbBlocks(0){ - FAssertLF(FMath::pow2(height) <= inDim); - FAssertLF(FMath::pow2(height-1) == nbPartitions); - - int currentNbPartitions = nbPartitions; - std::unique_ptr offsetUnknowns(new int[currentNbPartitions+1]); - offsetUnknowns[0] = 0; - for(int idxPartition = 1 ; idxPartition <= currentNbPartitions ; ++idxPartition){ - offsetUnknowns[idxPartition] = offsetUnknowns[idxPartition-1] + partitions[idxPartition-1]; - } - FAssertLF(offsetUnknowns[nbPartitions] == dim); - - nbLeaves = FMath::pow2(height-1); - leaves = new LeafNode[nbLeaves]; - totalNbBlocks += nbLeaves; - { - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - const int rowLeafNumber = idxLeaf; - const int colLeafNumber = idxLeaf; - leaves[idxLeaf].infos.row = offsetUnknowns[rowLeafNumber]; - leaves[idxLeaf].infos.col = offsetUnknowns[colLeafNumber]; - leaves[idxLeaf].infos.nbRows = offsetUnknowns[rowLeafNumber+1] - offsetUnknowns[rowLeafNumber]; - leaves[idxLeaf].infos.nbCols = offsetUnknowns[colLeafNumber+1] - offsetUnknowns[colLeafNumber]; - leaves[idxLeaf].infos.level = height; - } - } - - - cells = new CellNode*[height]; - FSetToZeros(cells, height); - nbCells = new int[height]; - FSetToZeros(nbCells, height); - - { - const int idxLevel = height-1; - const int nbCellsAtLevel = nbLeaves; - cells[idxLevel] = new CellNode[nbCellsAtLevel]; - nbCells[idxLevel] = nbCellsAtLevel; - totalNbBlocks += nbCellsAtLevel; - - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - const int rowLeafNumber = (idxLeaf^1); - const int colLeafNumber = idxLeaf; - cells[idxLevel][idxLeaf].infos.row = offsetUnknowns[rowLeafNumber]; - cells[idxLevel][idxLeaf].infos.col = offsetUnknowns[colLeafNumber]; - cells[idxLevel][idxLeaf].infos.nbRows = offsetUnknowns[rowLeafNumber+1] - offsetUnknowns[rowLeafNumber]; - cells[idxLevel][idxLeaf].infos.nbCols = offsetUnknowns[colLeafNumber+1] - offsetUnknowns[colLeafNumber]; - cells[idxLevel][idxLeaf].infos.level = height-1; - } - } - - for(int idxLevel = height-2 ; idxLevel >= 1 ; --idxLevel){ - const int nbCellsAtLevel = FMath::pow2(idxLevel); - cells[idxLevel] = new CellNode[nbCellsAtLevel]; - nbCells[idxLevel] = nbCellsAtLevel; - totalNbBlocks += nbCellsAtLevel; - - const int nbCellsInDirection = nbCells[idxLevel]; - - FAssertLF(nbCellsInDirection == currentNbPartitions/2); - currentNbPartitions = nbCellsInDirection; - for(int idxPartition = 1 ; idxPartition <= currentNbPartitions ; ++idxPartition){ - offsetUnknowns[idxPartition] = offsetUnknowns[idxPartition*2]; - } - FAssertLF(offsetUnknowns[currentNbPartitions] == dim); - - for(int idxCell = 0 ; idxCell < nbCellsAtLevel ; ++idxCell){ - const int rowCellNumber = (idxCell&1? idxCell-1 : idxCell+1); - const int colCellNumner = idxCell; - cells[idxLevel][idxCell].infos.row = offsetUnknowns[rowCellNumber]; - cells[idxLevel][idxCell].infos.col = offsetUnknowns[colCellNumner]; - cells[idxLevel][idxCell].infos.nbRows = offsetUnknowns[rowCellNumber+1] - offsetUnknowns[rowCellNumber]; - cells[idxLevel][idxCell].infos.nbCols = offsetUnknowns[colCellNumner+1] - offsetUnknowns[colCellNumner]; - cells[idxLevel][idxCell].infos.level = idxLevel; - } - } - } - - ~FStaticDiagonalBisection(){ - for(int idxLevel = 0 ; idxLevel < height ; ++idxLevel){ - delete[] cells[idxLevel]; - } - delete[] cells; - delete[] nbCells; - delete[] leaves; - } - - int getNbBlocks() const { - return totalNbBlocks; - } - - void forAllBlocksDescriptor(std::function callback){ - for(int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - for(int idxCell = 0 ; idxCell < nbCells[idxLevel] ; ++idxCell){ - callback(cells[idxLevel][idxCell].infos); - } - } - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - callback(leaves[idxLeaf].infos); - } - } - - void forAllCellBlocks(std::function callback){ - for(int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - for(int idxCell = 0 ; idxCell < nbCells[idxLevel] ; ++idxCell){ - callback(cells[idxLevel][idxCell].infos, - cells[idxLevel][idxCell].cell); - } - } - } - - void forAllLeafBlocks(std::function callback){ - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - callback(leaves[idxLeaf].infos, - leaves[idxLeaf].leaf); - } - } - - template - void fillBlocks(MatrixClass& matrix){ - for(int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - for(int idxCell = 0 ; idxCell < nbCells[idxLevel] ; ++idxCell){ - cells[idxLevel][idxCell].cell.fill(matrix.getBlock( - cells[idxLevel][idxCell].infos.row, - cells[idxLevel][idxCell].infos.col, - cells[idxLevel][idxCell].infos.nbRows, - cells[idxLevel][idxCell].infos.nbCols - ), - cells[idxLevel][idxCell].infos.level); - } - } - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - leaves[idxLeaf].leaf.fill(matrix.getBlock( - leaves[idxLeaf].infos.row, - leaves[idxLeaf].infos.col, - leaves[idxLeaf].infos.nbRows, - leaves[idxLeaf].infos.nbCols - ), - leaves[idxLeaf].infos.level); - } - } - - template - void fillBlocks(const MatrixClass& matrix){ - for(int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - for(int idxCell = 0 ; idxCell < nbCells[idxLevel] ; ++idxCell){ - cells[idxLevel][idxCell].cell.fill(matrix.getBlock( - cells[idxLevel][idxCell].infos.row, - cells[idxLevel][idxCell].infos.col, - cells[idxLevel][idxCell].infos.nbRows, - cells[idxLevel][idxCell].infos.nbCols - ), - cells[idxLevel][idxCell].infos.level); - } - } - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - leaves[idxLeaf].leaf.fill(matrix.getBlock( - leaves[idxLeaf].infos.row, - leaves[idxLeaf].infos.col, - leaves[idxLeaf].infos.nbRows, - leaves[idxLeaf].infos.nbCols - ), - leaves[idxLeaf].infos.level); - } - } - - void gemv(FReal res[], const FReal vec[]) const { - for(int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - for(int idxCell = 0 ; idxCell < nbCells[idxLevel] ; ++idxCell){ - cells[idxLevel][idxCell].cell.gemv(&res[cells[idxLevel][idxCell].infos.row], - &vec[cells[idxLevel][idxCell].infos.col]); - } - } - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - leaves[idxLeaf].leaf.gemv(&res[leaves[idxLeaf].infos.row], - &vec[leaves[idxLeaf].infos.col]); - } - } - - void gemm(FReal res[], const FReal mat[], const int nbRhs) const { - for(int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - for(int idxCell = 0 ; idxCell < nbCells[idxLevel] ; ++idxCell){ - cells[idxLevel][idxCell].cell.gemm(&res[cells[idxLevel][idxCell].infos.col], - &mat[cells[idxLevel][idxCell].infos.row], - nbRhs, dim); - } - } - for(int idxLeaf = 0 ; idxLeaf < nbLeaves ; ++idxLeaf){ - leaves[idxLeaf].leaf.gemm(&res[leaves[idxLeaf].infos.col], - &mat[leaves[idxLeaf].infos.row], - nbRhs, dim); - } - } - - static int GetNbPartitionsForHeight(const int inHeight){ - return FMath::pow2(inHeight-1); - } -}; - - -#endif // FSTATICDIAGONALBISECTION_HPP - diff --git a/Addons/HMat/Src/Utils/FHUtils.hpp b/Addons/HMat/Src/Utils/FHUtils.hpp deleted file mode 100644 index 0f26bc149234dcec3f0f46b377475c18dc33d2a4..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Utils/FHUtils.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FHUTILS_HPP -#define FHUTILS_HPP - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" - -#include - -template -void FSetToZeros(Type array[], const int length){ - memset(array, 0, length*sizeof(Type)); -} - - -struct FBlockDescriptor { - int row, col, nbRows, nbCols, level; -}; - -#endif // FHUTILS_HPP - diff --git a/Addons/HMat/Src/Utils/FMatrixIO.hpp b/Addons/HMat/Src/Utils/FMatrixIO.hpp deleted file mode 100644 index df29eef8ba43c44d0b216ebf023f4d6ce0bd0326..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Utils/FMatrixIO.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -// -// @SCALFMM_PRIVATE -// -#ifndef FMATRIXIO_HPP -#define FMATRIXIO_HPP - -// std includes -#include -#include -#include -#include -#include -#include - -// ScalFMM includes -#include "Utils/FGlobal.hpp" -#include "Utils/FParameters.hpp" -#include "Utils/FMath.hpp" - -/** - * @brief The FMatrixIO class - * Beware! Only handles sizes (nrows/ncols) representable by int32. - */ -class FMatrixIO { - -public: - - // Write matrix to binary file. - template - static void write(const FSize nrows, const FSize ncols, FReal* matrix, const std::string filename){ - - // store into binary file - std::ofstream stream(filename.c_str(), - std::ios::out | std::ios::binary | std::ios::trunc); - if (stream.good()) { - stream.seekp(0); - // 1) write number of rows (int) - //is_int(nrows); - int _nrows = int(nrows); - stream.write(reinterpret_cast(&_nrows), sizeof(int)); - // 2) write number of cols (int) - //is_int(ncols); - int _ncols = int(ncols); - stream.write(reinterpret_cast(&_ncols), sizeof(int)); - // 1) write matrix - stream.write(reinterpret_cast(matrix), sizeof(FReal)*nrows*ncols); - } - else throw std::runtime_error("File could not be opened to write"); - stream.close(); - - } - - // Read matrix from binary file. - // Also allocates memory! Please set matrix to nullptr before calling this function. - // nrows is just here to control the values that is read from file - // ncols is updated with the value read in the file (because it is not always known!) - template - static void read(const FSize nrows, FSize &ncols, FReal* &matrix, const std::string filename, const bool readSize = true){ - - // start reading process - if (matrix) throw std::runtime_error("Matrix is already set!"); - - std::ifstream stream(filename.c_str(), - std::ios::in | std::ios::binary | std::ios::ate); - const std::ifstream::pos_type size = stream.tellg(); - if (size<=0) { - std::cout << "Info: The requested binary file " << filename - << " does not yet exist. Compute it now ... " << std::endl; - return; - } - if (stream.good()) { - stream.seekg(0); - if(readSize){ - // 1) read number of rows (int) - int _nrows; - stream.read(reinterpret_cast(&_nrows), sizeof(int)); - //is_int(nrows); - if (_nrows!=int(nrows)) throw std::runtime_error("Read nrows and input nrows do not correspond"); - // 2) read number of cols (int) - int _ncols; - stream.read(reinterpret_cast(&_ncols), sizeof(int)); - //is_int(ncols); - ncols=_ncols; - } - // 3) read matrix - matrix = new FReal[nrows*ncols]; - stream.read(reinterpret_cast(matrix), sizeof(FReal)*nrows*ncols); - } else throw std::runtime_error("File could not be opened to read"); - stream.close(); - - } - - template - static bool read(const std::string filename, FReal** matrix, int* nbRows, int* nbCols){ - std::ifstream stream(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - - if (!stream.good()) { - return false; - } - - const std::ifstream::pos_type size = stream.tellg(); - if (size<=0) { - std::cout << "Info: The requested binary file " << filename - << " does not yet exist. Compute it now ... " << std::endl; - return false; - } - - stream.seekg(0); - - stream.read(reinterpret_cast(nbRows), sizeof(int)); - stream.read(reinterpret_cast(nbCols), sizeof(int)); - - delete[] (*matrix); - (*matrix) = new FReal[(*nbRows)*(*nbCols)]; - stream.read(reinterpret_cast((*matrix)), sizeof(FReal)*(*nbRows)*(*nbCols)); - - stream.close(); - return true; - } -}; - - -#endif // FMATRIXIO_HPP diff --git a/Addons/HMat/Src/Utils/FSvgRect.hpp b/Addons/HMat/Src/Utils/FSvgRect.hpp deleted file mode 100644 index a6af95e2ee4f9283e229e94ae67bf9558dbbd0d4..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Utils/FSvgRect.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FSVGRECT_HPP -#define FSVGRECT_HPP - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" -#include "Utils/FAssert.hpp" - -#include -#include - - -class FSvgRect { -protected: - int dim; - int svgSize; - int margin; - - int rectCounter; - double pixelperunknown; - int descriptiony; - - FILE* fsvg; - - std::vector> colors; - -public: - FSvgRect(const char inFilename[], const int inDim, - const int inSvgSize = 2048, const int inMargin = 50) - : dim(inDim), svgSize(inSvgSize), margin(inMargin), rectCounter(0), - pixelperunknown(0), descriptiony(0), fsvg(NULL){ - fsvg = fopen(inFilename, "w"); - FAssertLF(fsvg); - - pixelperunknown = double(svgSize-margin-margin*2)/double(dim); - - fprintf(fsvg, "\n"); - fprintf(fsvg, "\n" - "\n", - svgSize, svgSize); - fprintf(fsvg, "\n", - 0, 0,svgSize, svgSize, 255, 255, 255); - - descriptiony = int(svgSize - margin); - fprintf(fsvg, "Description: \n", 0, descriptiony); - - } - - FSvgRect(const char inDirname[], const char inFilename[], const int inDim, - const int inSvgSize = 2048, const int inMargin = 50) - : FSvgRect((std::string(inDirname)+std::string(inFilename)).c_str(), inDim, inSvgSize, inMargin) { - } - - ~FSvgRect(){ - fprintf(fsvg, ""); - fclose(fsvg); - } - - void addRect(const int inX, const int inY, const int inWidth, const int inHeight, const int inLevel = 0, const int rank = -1){ - if(int(colors.size()) <= inLevel){ - for(int idxColor = int(colors.size()) ; idxColor <= inLevel ; ++idxColor){ - colors.push_back(std::tuple(255*drand48(),255*drand48(),255*drand48())); - } - } - fprintf(fsvg, "\n", - int(margin + inX*pixelperunknown), - int(margin + inY*pixelperunknown), - int(inWidth*pixelperunknown), - int(inHeight*pixelperunknown), - std::get<0>(colors[inLevel]),std::get<1>(colors[inLevel]),std::get<2>(colors[inLevel])); - - if(rank != -1){ - fprintf(fsvg, "%d\n", - int(margin + inX*pixelperunknown) + 55, - int(margin + inY*pixelperunknown) + 55, - rank); - } - - rectCounter += 1; - } - - template - void addRectWithLegend(const int inX, const int inY, const int inWidth, const int inHeight, int inLevel = -1, const int rank = -1){ - if(int(colors.size()) <= inLevel){ - for(int idxColor = int(colors.size()) ; idxColor <= inLevel ; ++idxColor){ - colors.push_back(std::tuple(255*drand48(),255*drand48(),255*drand48())); - } - } - - fprintf(fsvg, "Description: X = %d, Y = %d, W = %d, H = %d, L = % d \n", - 0, descriptiony + svgSize, rectCounter, - inX, inY, inWidth, inHeight, inLevel); - - fprintf(fsvg, "(colors[inLevel]),std::get<1>(colors[inLevel]),std::get<2>(colors[inLevel])); - - fprintf(fsvg, " onmousedown=\"evt.target.parentNode.getElementById('res%d').setAttribute('y', '%d');\" ", - rectCounter,descriptiony); - fprintf(fsvg, " onmouseup=\"evt.target.parentNode.getElementById('res%d').setAttribute('y', '%d');\" ", - rectCounter,descriptiony + svgSize); - - fprintf(fsvg, "/>\n"); - - if(rank != -1){ - fprintf(fsvg, "%d\n", - int(margin + inX*pixelperunknown) + 55, - int(margin + inY*pixelperunknown) + 55, - rank); - } - - rectCounter += 1; - } -}; - -#endif // FSVGRECT_HPP - diff --git a/Addons/HMat/Src/Viewers/FDenseBlockPermWrapper.hpp b/Addons/HMat/Src/Viewers/FDenseBlockPermWrapper.hpp deleted file mode 100644 index 2604814c8711ac04090038a3e2084391af7a05e2..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Viewers/FDenseBlockPermWrapper.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef FDENSEBLOCKPERMWRAPPER_HPP -#define FDENSEBLOCKPERMWRAPPER_HPP - -// @SCALFMM_PRIVATE - -template -class FDenseBlockPermWrapper{ -protected: - const SrcMatrixClass& matrix; - const int row; - const int col; - const int nbRows; - const int nbCols; - -public: - FDenseBlockPermWrapper(const SrcMatrixClass& inMatrix, const int inRow, const int inCol, - const int inNbRows, const int inNbCols) - : matrix(inMatrix), row(inRow), col(inCol), - nbRows(inNbRows), nbCols(inNbCols) { - } - - int getNbRows() const { - return nbRows; - } - - int getNbCols() const { - return nbCols; - } - - FReal getValue(const int rowIdx, const int colIdx) const{ - FAssertLF(rowIdx < nbRows); - FAssertLF(colIdx < nbCols); - return matrix.getVal(row+rowIdx, col+colIdx); - } - - constexpr bool existsForReal() const{ - return true; - } -}; - -#endif // FDENSEBLOCKPERMWRAPPER_HPP - diff --git a/Addons/HMat/Src/Viewers/FDenseBlockWrapper.hpp b/Addons/HMat/Src/Viewers/FDenseBlockWrapper.hpp deleted file mode 100644 index d715f90265db98c69cfdba1bef6a1809a19afb38..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Viewers/FDenseBlockWrapper.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FDENSEBLOCKWRAPPER_HPP -#define FDENSEBLOCKWRAPPER_HPP - -// @SCALFMM_PRIVATE - -template -class FDenseBlockWrapper{ -protected: - const FReal* values; - const int nbRows; - const int nbCols; - const int leadingDim; - -public: - FDenseBlockWrapper(const FReal* inValues, const int inNbRows, const int inNbCols, const int inLeading) - : values(inValues), nbRows(inNbRows), nbCols(inNbCols), leadingDim(inLeading){ - } - - int getNbRows() const { - return nbRows; - } - - int getNbCols() const { - return nbCols; - } - - FReal getValue(const int rowIdx, const int colIdx) const{ - FAssertLF(rowIdx < nbRows); - FAssertLF(colIdx < nbCols); - return values[colIdx*leadingDim + rowIdx]; - } - - constexpr bool existsForReal() const{ - return true; - } -}; - -#endif // FDENSEBLOCKWRAPPER_HPP - diff --git a/Addons/HMat/Src/Viewers/FMatDense.hpp b/Addons/HMat/Src/Viewers/FMatDense.hpp deleted file mode 100644 index 95fe9d04d352f7ac0b7c643887263687456b1a47..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Viewers/FMatDense.hpp +++ /dev/null @@ -1,98 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== -#ifndef FMATDENSE_HPP -#define FMATDENSE_HPP - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" -#include "Utils/FAssert.hpp" - -#include "FDenseBlockWrapper.hpp" -#include "../Utils/FHUtils.hpp" -#include "../Utils/FMatrixIO.hpp" - -template -class FMatDense { -protected: - int matDim; - FReal* values; - - FMatDense(const FMatDense&) = delete; - FMatDense& operator=(const FMatDense&) = delete; -public: - using BlockDescriptor = FDenseBlockWrapper; - - explicit FMatDense(const int inDim, const FReal* inValues = nullptr) - : matDim(inDim), values(nullptr){ - values = new FReal[matDim*matDim]; - if(inValues){ - for(int idxVal = 0 ; idxVal < matDim*matDim ; ++idxVal){ - values[idxVal] = inValues[idxVal]; - } - } - else{ - FSetToZeros(values, matDim*matDim); - } - } - - explicit FMatDense(const char inFilename[]) - : matDim(0), values(nullptr){ - int readNbRows = 0; - int readNbCols = 0; - FAssertLF(FMatrixIO::read(inFilename, &values, &readNbRows, &readNbCols)); - FAssertLF(readNbRows == readNbCols); - matDim = readNbRows; - } - - ~FMatDense(){ - delete[] values; - } - - int getDim() const{ - return matDim; - } - - const FReal& getVal(const int idxRow , const int idxCol) const{ - return values[idxCol*matDim+idxRow]; - } - - FReal& getVal(const int idxRow , const int idxCol) { - return values[idxCol*matDim+idxRow]; - } - - void setVal(const int idxRow , const int idxCol, const FReal& val) { - values[idxCol*matDim+idxRow] = val; - } - - FDenseBlockWrapper getBlock(const int rowIdx, const int colIdx, const int nbRows, const int nbCols) const { - // static_assert(std::is_move_constructible::value, "The block class must be movable"); - // static_assert(std::is_move_assignable::value, "The block class must be movable"); - FAssertLF(0 < nbRows); - FAssertLF(0 < nbCols); - FAssertLF(rowIdx + nbRows <= matDim); - FAssertLF(colIdx + nbRows <= matDim); - return FDenseBlockWrapper(&values[colIdx*matDim+rowIdx], nbRows, nbCols, matDim); - } - - FDenseBlockWrapper getBlock(const FBlockDescriptor& info) const { - return getBlock(info.row, info.col, info.nbRows, info.nbCols); - } - -}; - -#endif // FMATDENSE_HPP - diff --git a/Addons/HMat/Src/Viewers/FMatDensePerm.hpp b/Addons/HMat/Src/Viewers/FMatDensePerm.hpp deleted file mode 100644 index ee0e5ae896a3c32e0fc8ccf9926d089392615aca..0000000000000000000000000000000000000000 --- a/Addons/HMat/Src/Viewers/FMatDensePerm.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef FMATDENSEPERM_HPP -#define FMATDENSEPERM_HPP - - -// @SCALFMM_PRIVATE - -#include "Utils/FGlobal.hpp" -#include "Utils/FAssert.hpp" - -#include "FDenseBlockPermWrapper.hpp" -#include "../Utils/FHUtils.hpp" -#include "../Utils/FMatrixIO.hpp" - -template -class FMatDensePerm { -protected: - int matDim; - FReal* values; - int* permOrigToNew; - - FMatDensePerm(const FMatDensePerm&) = delete; - FMatDensePerm& operator=(const FMatDensePerm&) = delete; -public: - using BlockDescriptor = FDenseBlockPermWrapper >; - - explicit FMatDensePerm(const int inDim, const FReal* inValues = nullptr, const int* inPermOrigToNew = nullptr) - : matDim(inDim), values(nullptr){ - values = new FReal[matDim*matDim]; - if(inValues){ - for(int idxVal = 0 ; idxVal < matDim*matDim ; ++idxVal){ - values[idxVal] = inValues[idxVal]; - } - } - else{ - FSetToZeros(values, matDim*matDim); - } - - permOrigToNew = new int[matDim]; - if(inPermOrigToNew){ - memcpy(permOrigToNew, inPermOrigToNew, sizeof(int)*matDim); - } - else { - for(int idxVal = 0 ; idxVal < matDim ; ++idxVal){ - permOrigToNew[idxVal] = idxVal; - } - } - } - - explicit FMatDensePerm(const char inFilename[], const int* inPermOrigToNew = nullptr) - : matDim(0), values(nullptr){ - int readNbRows = 0; - int readNbCols = 0; - FAssertLF(FMatrixIO::read(inFilename, &values, &readNbRows, &readNbCols)); - FAssertLF(readNbRows == readNbCols); - matDim = readNbRows; - - permOrigToNew = new int[matDim]; - if(inPermOrigToNew){ - memcpy(permOrigToNew, inPermOrigToNew, sizeof(int)*matDim); - } - else { - for(int idxVal = 0 ; idxVal < matDim ; ++idxVal){ - permOrigToNew[idxVal] = idxVal; - } - } - } - - ~FMatDensePerm(){ - delete[] values; - delete[] permOrigToNew; - } - - void setPermutOrigToNew(const int* inPermOrigToNew){ - memcpy(permOrigToNew, inPermOrigToNew, sizeof(int)*matDim); - } - - int getDim() const{ - return matDim; - } - - const FReal& getVal(const int idxRow , const int idxCol) const{ - return values[permOrigToNew[idxCol]*matDim+permOrigToNew[idxRow]]; - } - - FReal& getVal(const int idxRow , const int idxCol) { - return values[permOrigToNew[idxCol]*matDim+permOrigToNew[idxRow]]; - } - - void setVal(const int idxRow , const int idxCol, const FReal& val) { - values[permOrigToNew[idxCol]*matDim+permOrigToNew[idxRow]] = val; - } - - FDenseBlockPermWrapper > getBlock(const int rowIdx, const int colIdx, const int nbRows, const int nbCols) const { - // static_assert(std::is_move_constructible::value, "The block class must be movable"); - // static_assert(std::is_move_assignable::value, "The block class must be movable"); - FAssertLF(0 < nbRows); - FAssertLF(0 < nbCols); - FAssertLF(rowIdx + nbRows <= matDim); - FAssertLF(colIdx + nbCols <= matDim); - return FDenseBlockPermWrapper >(*this, rowIdx, colIdx, nbRows, nbCols); - } - - FDenseBlockPermWrapper > getBlock(const FBlockDescriptor& info) const { - return getBlock(info.row, info.col, info.nbRows, info.nbCols); - } -}; - -#endif // FMATDENSEPERM_HPP - diff --git a/Addons/HMat/Tests/testCCL.cpp b/Addons/HMat/Tests/testCCL.cpp deleted file mode 100644 index f9d4770bb2686801ff4f9e28c882daf845efb8f9..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testCCL.cpp +++ /dev/null @@ -1,76 +0,0 @@ - -// @SCALFMM_PRIVATE - -#include "../Src/Clustering/FCCLTreeCluster.hpp" -#include "../Src/Clustering/FClusterTree.hpp" -#include "../Src/Utils/FMatrixIO.hpp" - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - - FHelpDescribeAndExit(argc, argv,"Test the bisection.",SvgOutParam,DimParam,FParameterDefinitions::OctreeHeight); - - const char* filename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFile.options, "../Addons/HMat/Data/unitCube1000.bin"); - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 4); - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - - int readNbRows = 0; - int readNbCols = 0; - // Read distances - double* distances = nullptr; - FAssertLF(FMatrixIO::read(filename, &distances, &readNbRows, &readNbCols)); - FAssertLF(readNbRows == readNbCols); - const int dim = readNbRows; - - FCCLTreeCluster partitioner(dim, distances, CCL::CCL_TM_MAXIMUM /*CCL::CCL_TM_AVG_LINKAGE*/); - - FClusterTree tclusters; - partitioner.fillClusterTree(&tclusters); - tclusters.checkData(); - - std::unique_ptr permutations(new int[dim]); - tclusters.fillPermutations(permutations.get()); - - const int nbPartitions = FMath::pow2(height-1); - std::unique_ptr partitions(new int[nbPartitions]); - tclusters.getPartitions(height, nbPartitions, partitions.get()); - - { - typedef double FReal; - typedef FDenseBlock LeafClass; - typedef FDenseBlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - GridClass bissection(dim, height, partitions.get(), nbPartitions); - - FSvgRect output(outputdir, "ccl.svg", dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - tclusters.saveToXml(outputdir, "ccl.xml"); - - tclusters.saveToDot(outputdir, "gccl.dot"); - - return 0; -} - diff --git a/Addons/HMat/Tests/testCCLKCluster.cpp b/Addons/HMat/Tests/testCCLKCluster.cpp deleted file mode 100644 index f3aca4154dfb66d2e3acdb331b545e3cabe3c3a4..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testCCLKCluster.cpp +++ /dev/null @@ -1,242 +0,0 @@ - -// @SCALFMM_PRIVATE - -// HMAT specific includes -#include "../Src/Clustering/FCCLKCluster.hpp" -#include "../Src/Utils/FMatrixIO.hpp" - -#include "../Src/Containers/FPartitionsMapping.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -// ScalFMM's include -#include "Files/FFmaGenericLoader.hpp" // load grid -#include "Utils/FGlobal.hpp" -#include "Utils/FTic.hpp" -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames ElemParam = { - {"-nE", "-nbElements", "-elem"} , - "Nbof elements to partition." - }; - static const FParameterNames DimParam = { - {"-nD", "-nbDim", "-dim"} , - "Dimension of ambiant space." - }; - static const FParameterNames NbPartitionsParam = { - {"-Part", "-nbPartitions", "-nbClusters"} , - "Dim of the matrix." - }; - static const FParameterNames NbPassesParam = { - {"-Pass", "-nbPasses", "-nbPass"} , - "Dim of the matrix." - }; - - //FHelpDescribeAndExit(argc, argv,"Test the k-means, k-medians and k-medoids algorithms from CCL (using 2 methods for distance computation) on 3D grid (unitCube).",SvgOutParam,ElemParam,DimParam,NbPartitionsParam,NbPassesParam,FParameterDefinitions::InputFile); - - //////////////////////////////////////////////////////////////////// - /// Command line examples - // Partition the unitCube with 1000 particles in 8 partitions (use 5 iterations of EM algorithm) - // ./Addons/HMat/testCCLKCluster -binin -nE 1000 -d unitCube -Part 8 -Pass 5 - // > Results show that k-medoids seems to work better for unitCube1000 (use fewer pass, but still more costly) - // - // - //////////////////////////////////////////////////////////////////// - /// Parameters - // size of the grid - const int nbElements = FParameters::getValue(argc,argv,"-nE", 1000); - - // size of the grid - const int nbDim = FParameters::getValue(argc,argv,"-nD", 3); - - // Define number of partitions - const int nbPartitions = FParameters::getValue(argc, argv, NbPartitionsParam.options, 4); - - // Define number of passes - const int nbPasses = FParameters::getValue(argc, argv, NbPassesParam.options, 5); - - // Precision - typedef double FReal; - if(sizeof(FReal)==4) - std::cout<< "Precision: Single Float" < partitioner(nbPartitions, nbElements, distances, nbPasses); - - tKMedoids = timeKMedoids.tacAndElapsed(); - std::cout << "... took @tKMedoids = "<< tKMedoids <<"\n"; - - std::unique_ptr partitions(new int[nbPartitions]); - partitioner.getPartitions(nbPartitions,partitions.get()); - { - typedef FDenseBlock CellClass; - typedef FPartitionsMapping GridClass; - - GridClass bissection(nbElements, partitions.get(), nbPartitions); - - char svgName[1024]; - sprintf(svgName, "%s/%s-%s-P%d.svg", outputdir, distributionName.c_str(), "CCL_KMEDOIDS", nbPartitions); - FSvgRect output(svgName, nbElements); - std::cout << "\tSave svg to " << svgName << "\n"; - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - } - - } - - - // Compute partitions from data matrix (i.e. grid) - { - - // Read geometry - std::string distributionFileName = ioPath + distributionName; - if( FParameters::existParameter(argc, argv, FParameterDefinitions::InputBinFormat.options)){ - distributionFileName += ".bfma"; - } - else { - distributionFileName += ".fma"; - } - - std::cout << "Data matrix read from file:" << distributionFileName << std::endl; - - // open particle file - FFmaGenericLoader loader(distributionFileName.c_str()); - if(!loader.isOpen()) throw std::runtime_error("Particle distribution file couldn't be opened!"); - - //////////////////////////////////////////////////////////////////// - /// Load grid from distribution file - //FPoint* grid = new FPoint[nbElements]; - FReal* grid = new FReal[nbElements*nbDim]; - - for(FSize idxPart = 0 ; idxPart < nbElements ; ++idxPart){ - FPoint position; - FReal physicalValue = 0.0; - loader.fillParticle(&position,&physicalValue); - //grid[idxPart]=position; - grid[idxPart+0*nbElements]=position.getX(); - grid[idxPart+1*nbElements]=position.getY(); - grid[idxPart+2*nbElements]=position.getZ(); - } - - - // Test Cluster Center Method K-MEANS - { - FTic timeKMeans; - double tKMeans; - timeKMeans.tic(); - - FCCLKCluster partitioner(nbPartitions, nbElements, nbDim, grid, CCL::CCL_CCM_ARITHMETIC_MEAN, CCL::CCL_DIST_MEAN, nbPasses); - - tKMeans = timeKMeans.tacAndElapsed(); - std::cout << "... took @tKMeans = "<< tKMeans <<"\n"; - - - std::unique_ptr partitions(new int[nbPartitions]); - partitioner.getPartitions(nbPartitions,partitions.get()); - { - typedef FDenseBlock CellClass; - typedef FPartitionsMapping GridClass; - - GridClass bissection(nbElements, partitions.get(), nbPartitions); - - char svgName[1024]; - sprintf(svgName, "%s/%s-%s-P%d.svg", outputdir, distributionName.c_str(), "CCL_KMEANS_DIST_MEAN", nbPartitions); - FSvgRect output(svgName, nbElements); - std::cout << "\tSave svg to " << svgName << "\n"; - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - } - - // Test Cluster Center Method K-MEDIANS - { - FTic timeKMedians; - double tKMedians; - timeKMedians.tic(); - - FCCLKCluster partitioner(nbPartitions, nbElements, nbDim, grid, CCL::CCL_CCM_MEDIAN, CCL::CCL_DIST_MEAN, nbPasses); - - tKMedians = timeKMedians.tacAndElapsed(); - std::cout << "... took @tKMedians = "<< tKMedians <<"\n"; - - std::unique_ptr partitions(new int[nbPartitions]); - partitioner.getPartitions(nbPartitions,partitions.get()); - { - typedef FDenseBlock CellClass; - typedef FPartitionsMapping GridClass; - - GridClass bissection(nbElements, partitions.get(), nbPartitions); - - char svgName[1024]; - sprintf(svgName, "%s/%s-%s-P%d.svg", outputdir, distributionName.c_str(), "CCL_KMEDIANS_DIST_MEAN", nbPartitions); - FSvgRect output(svgName, nbElements); - std::cout << "\tSave svg to " << svgName << "\n"; - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - } - - } - - - - return 0; -} - diff --git a/Addons/HMat/Tests/testCompareClusteringRank.cpp b/Addons/HMat/Tests/testCompareClusteringRank.cpp deleted file mode 100644 index cbedf4f7d8a36865c59cbf78b8af01cfd9d1bead..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testCompareClusteringRank.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Viewers/FMatDensePerm.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" -#include "../Src/Blocks/FSVDBlock.hpp" -#include "../Src/Blocks/FACABlock.hpp" - -#include "../Src/Clustering/FMaxDistCut.hpp" -#include "../Src/Clustering/FCCLTreeCluster.hpp" -#include "../Src/Clustering/FGraphThreshold.hpp" - -#include "../Src/Utils/FSvgRect.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include "Utils/FTic.hpp" - -#include - -template -void CheckRank(const FClusterTree& ctree, MatrixClass& matrix, - const char outputdir[], const char configName[], const int height){ - - typedef FDenseBlock LeafClass; - typedef FACABlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - const int dim = matrix.getDim(); - std::unique_ptr permutationOrgToNew(new int[dim]); - - for( int idxLevel = 1 ; idxLevel < height ; ++idxLevel){ - const int nbPartitions = FMath::pow2(idxLevel); - std::unique_ptr partitions(new int[nbPartitions]); - ctree.getPartitions(idxLevel+1, nbPartitions, partitions.get()); - - ctree.fillPermutations(permutationOrgToNew.get()); - matrix.setPermutOrigToNew(permutationOrgToNew.get()); - - std::cout << "\tLevel " << idxLevel << " build blocks\n"; - FTic timer; - GridClass grid(dim, idxLevel+1, partitions.get(), nbPartitions); - grid.fillBlocks(matrix); - std::cout << "\tdone in " << timer.tacAndElapsed() << "s\n"; - - { - char svgName[1024]; - sprintf(svgName, "%s/%s-%d.svg", outputdir, configName, idxLevel); - std::cout << "\tSave svg to " << svgName << "\n"; - - FSvgRect output(svgName, dim); - - grid.forAllCellBlocks([&](const FBlockDescriptor& info, const CellClass& cell){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level, cell.getRank()); - }); - - grid.forAllLeafBlocks([&](const FBlockDescriptor& info, const LeafClass& /*leaf*/){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - } -} - -int main(int argc, char** argv){ - - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - - FHelpDescribeAndExit(argc, argv, "Test the rank for different clustering.", - FParameterDefinitions::InputFileOne, - FParameterDefinitions::InputFileTwow, - FParameterDefinitions::OctreeHeight, - SvgOutParam); - - //////////////////////////////////////////////////////////////////// - - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - //const char* distanceFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileOne.options, "../Addons/HMat/Data/unitCube1000.bin"); - //const char* matrixFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileTwow.options, "../Addons/HMat/Data/unitCube1000_ONE_OVER_R.bin"); - const char* distanceFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileOne.options, "../Addons/HMat/Data/unitSphere1000.bin"); - const char* matrixFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileTwow.options, "../Addons/HMat/Data/unitSphere1000_GAUSS100.bin"); - typedef double FReal; - - //const char* distanceFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileOne.options, "../Addons/HMat/Data/first_reads_1k-fmr-dissw.bin"); - //const char* matrixFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileTwow.options, "../Addons/HMat/Data/first_reads_1k-fmr-covar.bin"); - //typedef float FReal; - - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 4); - - std::cout << "Check until height = " << height << "\n"; - - typedef FMatDensePerm MatrixClass; - - //////////////////////////////////////////////////////////////////// - - std::cout << "Load distances file " << distanceFilename << "\n"; - - std::unique_ptr distanceValues; - int distanceValuesDim = 0; - { - int readNbRows = 0; - int readNbCols = 0; - FReal* distanceValuesPtr = nullptr; - FAssertLF(FMatrixIO::read(distanceFilename, &distanceValuesPtr, &readNbRows, &readNbCols)); - FAssertLF(readNbRows == readNbCols); - distanceValuesDim = readNbRows; - distanceValues.reset(distanceValuesPtr); - } - - //////////////////////////////////////////////////////////////////// - - std::cout << "Load matrix file " << matrixFilename << "\n"; - - MatrixClass matrix(matrixFilename); - const int matrixDim = matrix.getDim(); - - // Display covariance matrix - const FSize displaySize = 10; - std::cout<<"\nC=["< partitioner(matrixDim, distanceValues.get()); - - FClusterTree tclusters; - partitioner.fillClusterTree(&tclusters); - tclusters.checkData(); - CheckRank(tclusters, matrix, outputdir, "FMaxDistCut", height); - } - //////////////////////////////////////////////////////////////////// - { - std::cout << "Test FGraphThreshold\n"; - FGraphThreshold partitioner(matrixDim, distanceValues.get(), FGraphThreshold::GetDefaultRadius(matrixDim, distanceValues.get())); - - FClusterTree tclusters; - partitioner.fillClusterTree(&tclusters); - tclusters.checkData(); - CheckRank(tclusters, matrix, outputdir, "FGraphThreshold", height); - } - //////////////////////////////////////////////////////////////////// - { - std::cout << "Test FCCLTreeCluster\n"; - FCCLTreeCluster partitioner(matrixDim, distanceValues.get(), CCL::CCL_TM_MAXIMUM); - - FClusterTree tclusters; - partitioner.fillClusterTree(&tclusters); - tclusters.checkData(); - CheckRank(tclusters, matrix, outputdir, "FCCLTreeCluster", height); - } - - return 0; -} - - diff --git a/Addons/HMat/Tests/testConnectClustering.cpp b/Addons/HMat/Tests/testConnectClustering.cpp deleted file mode 100644 index 39c829ddd14d62411ebeafa1fc260491b4ec4ace..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testConnectClustering.cpp +++ /dev/null @@ -1,192 +0,0 @@ - -// @SCALFMM_PRIVATE - -#include "../Src/Clustering/FConnexClustering.hpp" -#include "../Src/Utils/FMatrixIO.hpp" - -#include "../Src/Containers/FPartitionsMapping.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include "Files/FGenerateDistribution.hpp" - -#include - -// FUSE_SCOTCH - -template -void TestPartitions(const PartitionerClass& partitioner, - const char outputdir[], const int idFile, - const int dim, - const FReal coords[], const char config[]){ - - std::unique_ptr permutations(new int[dim]); - std::unique_ptr invpermutations(new int[dim]); - partitioner.fillPermutations(permutations.get(), invpermutations.get()); - - const int nbPartitions = partitioner.getNbPartitions(); - std::unique_ptr partitions(new int[nbPartitions]); - partitioner.getPartitions(nbPartitions, partitions.get()); - - if(coords!=nullptr) - { - char coordfilename[1024]; - sprintf(coordfilename, "%s/%s-coord-%d.csv", outputdir, config, idFile); - std::cout << "\t save coord to " << coordfilename << "\n"; - FILE* fcoord = fopen(coordfilename, "w"); - - int offsetParticles = 0; - for(int idxPartition = 0 ; idxPartition < nbPartitions ; ++idxPartition){ - for(int idxPart = 0 ; idxPart < partitions[idxPartition] ; ++idxPart){ - const int idxUnk = invpermutations[idxPart+offsetParticles]; - fprintf(fcoord, "%e,%e,%e,%d\n", - coords[idxUnk*4 + 0], - coords[idxUnk*4 + 1], - coords[idxUnk*4 + 2], - idxPartition); - } - offsetParticles += partitions[idxPartition]; - } - FAssertLF(offsetParticles == dim); - - fclose(fcoord); - } - { - typedef FDenseBlock CellClass; - typedef FPartitionsMapping GridClass; - - GridClass bissection(dim, partitions.get(), nbPartitions); - - char svgfilename[1024]; - sprintf(svgfilename, "%s/%s-%d.svg", outputdir, config, idFile); - std::cout << "\t save svg to " << svgfilename << "\n"; - FSvgRect output(svgfilename, dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } -} - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - - FHelpDescribeAndExit(argc, argv,"Test the bisection.",SvgOutParam,DimParam, - FParameterDefinitions::InputFileOne, - FParameterDefinitions::InputFileTwow, - FParameterDefinitions::NbParticles); - - const int nbParticles = (FParameters::getValue(argc, argv, FParameterDefinitions::NbParticles.options, 3000) & ~1); - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - - typedef float FReal; - - //////////////////////////////////////////////////////////////////// - - const char* distanceFilename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileOne.options, "../Addons/HMat/Data/unitCube1000.bin"); - - //////////////////////////////////////////////////////////////////// - - std::cout << "Load distances file " << distanceFilename << "\n"; - - std::unique_ptr particles(nullptr); - std::unique_ptr distances; - int dim = 0; - { - int readNbRows = 0; - int readNbCols = 0; - FReal* distanceValuesPtr = nullptr; - FAssertLF(FMatrixIO::read(distanceFilename, &distanceValuesPtr, &readNbRows, &readNbCols)); - FAssertLF(readNbRows == readNbCols); - dim = readNbRows; - distances.reset(distanceValuesPtr); - } - - - const FSize displaySize=10; - std::cout<<"\nD=["< particles(new FReal[nbParticles*4]); -// unifRandonPointsOnSphere(nbPointsSphere, radius, particles.get()) ; -// -// for(int idxPoint = 0 ; idxPoint < nbPointsSphere ; ++idxPoint){ -// particles[(idxPoint+nbPointsSphere)*4 + 0] = particles[idxPoint*4 + 0] + radius*2 + distanceBetweenSpheres; -// particles[(idxPoint+nbPointsSphere)*4 + 1] = particles[idxPoint*4 + 1] + radius*2 + distanceBetweenSpheres; -// particles[(idxPoint+nbPointsSphere)*4 + 2] = particles[idxPoint*4 + 2] + radius*2 + distanceBetweenSpheres; -// } -// -// ///////////////////////////////////////////////////////////////// -// -// std::cout << "Compute distance\n"; -// -// const int dim = nbParticles; -// std::unique_ptr distances(new FReal[nbParticles*nbParticles]); -// for(int idxCol = 0 ; idxCol < nbParticles ; ++idxCol){ -// for(int idxRow = 0 ; idxRow < nbParticles ; ++idxRow){ -// const FReal diffx = particles[idxCol*4 + 0] - particles[idxRow*4 + 0]; -// const FReal diffy = particles[idxCol*4 + 1] - particles[idxRow*4 + 1]; -// const FReal diffz = particles[idxCol*4 + 2] - particles[idxRow*4 + 2]; -// distances[idxCol*nbParticles+idxRow] = FMath::Sqrt((diffx*diffx) + (diffy*diffy) + (diffz*diffz)); -// } -// } -// -// ///////////////////////////////////////////////////////////////// - - FReal distMin = std::numeric_limits::max(); - FReal distMax = std::numeric_limits::min(); - - for(int idxRow = 0 ; idxRow < dim ; ++idxRow){ - for(int idxCol = idxRow ; idxCol < dim ; ++idxCol){ - distMin = FMath::Min(distMin, distances[idxCol*nbParticles+idxRow]); - distMax = FMath::Max(distMax, distances[idxCol*nbParticles+idxRow]); - } - } - std::cout << "Dist min " << distMin << "\n"; - std::cout << "Dist max " << distMax << "\n"; - - ///////////////////////////////////////////////////////////////// - const FReal stepThresh = (distMax-distMin)/100; - for(FReal thresh = distMin ; thresh <= distMax/10 ; thresh += stepThresh){ - std::cout << "Test FConnexClustering for thresh " << thresh << "\n"; - FConnexClustering partitioner(dim, distances.get(), thresh); - std::cout << "\tGot " << partitioner.getNbPartitions() << " partitions\n"; - TestPartitions>(partitioner,outputdir, - int((thresh-distMin)/stepThresh), - dim, particles.get(), "FConnexClustering"); - } - - return 0; -} - - - - diff --git a/Addons/HMat/Tests/testGenerateKernelMatrix.cpp b/Addons/HMat/Tests/testGenerateKernelMatrix.cpp deleted file mode 100644 index c8382d3c00d3c836106e9445180dd20f3773200e..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testGenerateKernelMatrix.cpp +++ /dev/null @@ -1,220 +0,0 @@ - -// @SCALFMM_PRIVATE - -#include -#include - -#include -#include -#include -#include // for normal distribution generator -#include // for sort - - -// ScalFMM includes -#include "Files/FFmaGenericLoader.hpp" -#include "Utils/FGlobal.hpp" -#include "Utils/FTic.hpp" -#include "Utils/FParameters.hpp" -#include "Utils/FMemUtils.hpp" -#include "Utils/FBlas.hpp" // for FBlas::potrf (and QR,SVD...) -#include "Utils/FMath.hpp" -#include "Utils/FParameterNames.hpp" - -#include "Kernels/Interpolation/FInterpMatrixKernel.hpp" // for kernel matrices -#include "Kernels/Interpolation/FInterpMatrixKernel_Covariance.hpp" // for kernel matrices - -// not mandatory but useful to define some flags -#include "Core/FFmmAlgorithm.hpp" -#include "Core/FFmmAlgorithmThread.hpp" - -// ScalFMM/HMat includes -#include "../Src/Utils/FMatrixIO.hpp" - -/** -* In this file we explicitely build a kernel matrix and then store it in a binary file. -* -* Author: Pierre Blanchard (pierre.blanchard@inria.fr) -* Date created: November 26th, 2015 -*/ - - -int main(int argc, char* argv[]) -{ - std::cout << "Addons/HMat: Build a kernel matrix and then store it in a binary file." << std::endl; - - // Example for unitCube5000 - // ./Addons/HMat/testGenerateKernelMatrix -binin -N 5000 -d unitCube5000 - - //////////////////////////////////////////////////////////////////// - /// Timers - FTic time; - time.tic(); - - //////////////////////////////////////////////////////////////////// - /// Parameters - // Verbose (print matrices) - const int verbose = FParameters::getValue(argc, argv, "-v", 0); - std::cout<< "Verbose level: " << verbose < loader(distributionFileName.c_str()); - if(!loader.isOpen()) throw std::runtime_error("Particle distribution file couldn't be opened!"); - - //////////////////////////////////////////////////////////////////// - /// Load 3D grid from distribution file - FPoint* grid = new FPoint[matrixSize]; - FReal* pV = new FReal[matrixSize]; - - for(FSize idxPart = 0 ; idxPart < matrixSize ; ++idxPart){ - FPoint position; - FReal physicalValue = 0.0; - loader.fillParticle(&position,&physicalValue); - grid[idxPart]=position; - pV[idxPart]=physicalValue; - } - - -{ - //////////////////////////////////////////////////////////////////// - /// Build kernel matrix K - - // Interaction kernel evaluator - //typedef FInterpMatrixKernelR MatrixKernelClass; - typedef CK_Gauss MatrixKernelClass; - const FReal lengthScale = FReal(0.01)*FParameters::getValue(argc,argv,"-lengthscale", FReal(100.)); - std::ostringstream oss; oss << 100*lengthScale; - const MatrixKernelClass MatrixKernel(lengthScale); - const std::string MatrixKernelID = MatrixKernelClass::getID() + oss.str() ;//.c_str(); - - // Allocate memory - FReal* K = new FReal[matrixSize*matrixSize]; - FBlas::setzero(int(matrixSize*matrixSize),K); - - // Build (symmetric) kernel matrix - FTic timeAssK; - for(FSize idxRow = 0 ; idxRow < matrixSize ; ++idxRow) - for(FSize idxCol = idxRow+1 ; idxCol < matrixSize ; ++idxCol) { - K[idxRow*matrixSize+idxCol] = MatrixKernel.evaluate(grid[idxRow], - grid[idxCol]); - K[idxCol*matrixSize+idxRow] = K[idxRow*matrixSize+idxCol]; - } - - double tAssK = timeAssK.tacAndElapsed(); - std::cout << "... took @tAssK = "<< tAssK <<"\n"; - - // Display matrix - const FSize displaySize = 10; - if(verbose==2) { - std::cout<<"\nK=["<(matrixSize,matrixSize,K,fileName); - - tWriteMat = timeWriteMat.tacAndElapsed(); - std::cout << "... took @tWriteMat = "<< tWriteMat <<"\n"; -} -{ - //////////////////////////////////////////////////////////////////// - /// Build distance matrix D - - // Allocate memory - FReal* D = new FReal[matrixSize*matrixSize]; - FBlas::setzero(int(matrixSize*matrixSize),D); - - // Build (symmetric) kernel matrix - FTic timeAssK; - - for(FSize idxRow = 0 ; idxRow < matrixSize ; ++idxRow) - for(FSize idxCol = idxRow ; idxCol < matrixSize ; ++idxCol) { - FReal diffX(grid[idxRow].getX()-grid[idxCol].getX()); - FReal diffY(grid[idxRow].getY()-grid[idxCol].getY()); - FReal diffZ(grid[idxRow].getZ()-grid[idxCol].getZ()); - D[idxRow*matrixSize+idxCol] = FMath::Sqrt(diffX*diffX+diffY*diffY+diffZ*diffZ); - if(idxCol!=idxRow) - D[idxCol*matrixSize+idxRow] = D[idxRow*matrixSize+idxCol]; - } - - double tAssK = timeAssK.tacAndElapsed(); - std::cout << "... took @tAssK = "<< tAssK <<"\n"; - - // Display matrix - const FSize displaySize = 10; - if(verbose==2) { - std::cout<<"\nD=["<(matrixSize,matrixSize,D,fileName); - - tWriteMat = timeWriteMat.tacAndElapsed(); - std::cout << "... took @tWriteMat = "<< tWriteMat <<"\n"; - - - double tOverall = time.tacAndElapsed(); - std::cout << "... took @tOverall = "<< tOverall <<"\n"; -} - - return 0; -} diff --git a/Addons/HMat/Tests/testGraphTreshold.cpp b/Addons/HMat/Tests/testGraphTreshold.cpp deleted file mode 100644 index ec5cb015d51b85f76c80f7f60aff3d31f965acf5..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testGraphTreshold.cpp +++ /dev/null @@ -1,85 +0,0 @@ - -// @SCALFMM_PRIVATE - -#include "../Src/Clustering/FCCLTreeCluster.hpp" -#include "../Src/Clustering/FGraphThreshold.hpp" -#include "../Src/Utils/FMatrixIO.hpp" - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include - -// FUSE_SCOTCH - - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - - FHelpDescribeAndExit(argc, argv,"Test the bisection.",SvgOutParam,DimParam,FParameterDefinitions::OctreeHeight); - - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 4); - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - - //const char* filename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFile.options, "../Addons/HMat/Data/unitCube1000.bin"); - //typedef double FReal; - - const char* filename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFileOne.options, "../Addons/HMat/Data/first_reads_1k-fmr-dissw.bin"); - typedef float FReal; - - int readNbRows = 0; - int readNbCols = 0; - // Read distances - FReal* distances = nullptr; - FAssertLF(FMatrixIO::read(filename, &distances, &readNbRows, &readNbCols)); - FAssertLF(readNbRows == readNbCols); - const int dim = readNbRows; - - FGraphThreshold partitioner(dim, distances, FGraphThreshold::GetDefaultRadius(dim, distances)); - - FClusterTree tclusters; - partitioner.fillClusterTree(&tclusters); - tclusters.checkData(); - - std::unique_ptr permutations(new int[dim]); - tclusters.fillPermutations(permutations.get()); - - const int nbPartitions = FMath::pow2(height-1); - std::unique_ptr partitions(new int[nbPartitions]); - tclusters.getPartitions(height, nbPartitions, partitions.get()); - - { - //typedef double FReal; - typedef FDenseBlock LeafClass; - typedef FDenseBlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - GridClass bissection(dim, height, partitions.get(), nbPartitions); - - FSvgRect output(outputdir, "scotch.svg", dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - tclusters.saveToXml(outputdir, "scotch.xml"); - - tclusters.saveToDot(outputdir, "gscotch.dot"); - - return 0; -} - - diff --git a/Addons/HMat/Tests/testPartitionsMapping.cpp b/Addons/HMat/Tests/testPartitionsMapping.cpp deleted file mode 100644 index cede5a9f1ae4a500fbf545e4cf8c6fe66adaa51a..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testPartitionsMapping.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FPartitionsMapping.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - static const FParameterNames PartitionsParam = { - {"-part", "-parts", "-nbparts"} , - "Number of partitions." - }; - - FHelpDescribeAndExit(argc, argv,"Test the bisection.",SvgOutParam,DimParam,FParameterDefinitions::OctreeHeight); - - const int dim = FParameters::getValue(argc, argv, DimParam.options, 100); - const int nbPartitions = FParameters::getValue(argc, argv, PartitionsParam.options, 9); - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - - std::cout << "Config : dim = " << dim << "\n"; - std::cout << "Config : nbPartitions = " << nbPartitions << "\n"; - std::cout << "Config : outputdir = " << outputdir << "\n"; - - typedef double FReal; - typedef FDenseBlock CellClass; - typedef FPartitionsMapping GridClass; - - { - std::unique_ptr partitions(new int[nbPartitions]); - { - int nbValuesLeft = dim; - for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){ - partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition)))); - nbValuesLeft -= partitions[idxPartition]; - } - partitions[nbPartitions-1] = nbValuesLeft; - } - - GridClass bissection(dim, partitions.get(), nbPartitions); - - FSvgRect output(outputdir, "partitionednp", dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - return 0; -} - diff --git a/Addons/HMat/Tests/testPartitionsMappingGemv.cpp b/Addons/HMat/Tests/testPartitionsMappingGemv.cpp deleted file mode 100644 index bd5131c8a3d08670a53c9fc3520b23cc85f2a907..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testPartitionsMappingGemv.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FPartitionsMapping.hpp" -#include "../Src/Viewers/FMatDense.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" -#include "Utils/FTic.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - static const FParameterNames PartitionsParam = { - {"-part", "-parts", "-nbparts"} , - "Number of partitions." - }; - - FHelpDescribeAndExit(argc, argv, "Test the bisection.", DimParam, FParameterDefinitions::OctreeHeight); - - const int dim = FParameters::getValue(argc, argv, DimParam.options, 100); - const int nbPartitions = FParameters::getValue(argc, argv, PartitionsParam.options, 5); - - std::cout << "Config : dim = " << dim << "\n"; - std::cout << "Config : nbPartitions = " << nbPartitions << "\n"; - - FTic time; - - typedef double FReal; - typedef FMatDense MatrixClass; - - MatrixClass matrix(dim); - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - matrix.setVal(idxRow, idxCol, 1./(FMath::Abs(FReal(idxRow-idxCol))+1.)); - } - } - - std::unique_ptr vec(new FReal[dim]); - for(int idxVal = 0 ; idxVal < dim ; ++idxVal){ - vec[idxVal] = 1.0; - } - - std::unique_ptr resTest(new FReal[dim]); - FSetToZeros(resTest.get(), dim); - { - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - resTest[idxRow] += vec[idxCol] * matrix.getVal(idxRow, idxCol); - } - } - } - - { - typedef FDenseBlock CellClass; - typedef FPartitionsMapping GridClass; - - std::unique_ptr partitions(new int[nbPartitions]); - { - int nbValuesLeft = dim; - for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){ - partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition)))); - nbValuesLeft -= partitions[idxPartition]; - } - partitions[nbPartitions-1] = nbValuesLeft; - } - - GridClass grid(dim, partitions.get(), nbPartitions); - grid.fillBlocks(matrix); - - std::unique_ptr resDense(new FReal[dim]); - FSetToZeros(resDense.get(), dim); - - grid.gemv(resDense.get(), vec.get()); - - FMath::FAccurater testDense(resTest.get(), resDense.get(), dim); - - std::cout << "Test Dense partitions mapping, Error = " << testDense << "\n"; - } - - return 0; -} - - diff --git a/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp b/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp deleted file mode 100644 index 7ae84e23630303b6fc45251eb8054853990d9b2a..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testPartitionsMappingGemvBlock.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FBlockPMapping.hpp" -#include "../Src/Viewers/FMatDensePerm.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - static const FParameterNames PartitionsParam = { - {"-part", "-parts", "-nbparts"} , - "Number of partitions." - }; - - FHelpDescribeAndExit(argc, argv, "Test the bisection.", DimParam, FParameterDefinitions::OctreeHeight); - - const int dim = FParameters::getValue(argc, argv, DimParam.options, 100); - const int nbPartitions = FParameters::getValue(argc, argv, PartitionsParam.options, 5); - - std::cout << "Config : dim = " << dim << "\n"; - std::cout << "Config : nbPartitions = " << nbPartitions << "\n"; - - - typedef double FReal; - typedef FMatDensePerm MatrixClass; - - MatrixClass matrix(dim); - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - matrix.setVal(idxRow, idxCol, 1./(FMath::Abs(FReal(idxRow-idxCol))+1.)); - } - } - - { // Here we fill the block manually - // We consider a fack permutation - std::unique_ptr permutations(new int[dim]); - for(int idx = 0 ; idx < dim ; ++idx){ - permutations[idx] = idx; - } - // Set permutation to matrix - matrix.setPermutOrigToNew(permutations.get()); - } - - std::unique_ptr vec(new FReal[dim]); - for(int idxVal = 0 ; idxVal < dim ; ++idxVal){ - vec[idxVal] = 1.0; - } - - std::unique_ptr resTest(new FReal[dim]); - FSetToZeros(resTest.get(), dim); - { - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - resTest[idxRow] += vec[idxCol] * matrix.getVal(idxRow, idxCol); - } - } - } - - { - typedef FDenseBlock CellClass; - typedef FBlockPMapping GridClass; - - std::unique_ptr partitions(new int[nbPartitions]); - { - int nbValuesLeft = dim; - for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){ - partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition)))); - nbValuesLeft -= partitions[idxPartition]; - } - partitions[nbPartitions-1] = nbValuesLeft; - } - - GridClass grid(dim, partitions.get(), nbPartitions); - - // We iterate on the blocks - // V blocks cover all the rows, but only some columns (based on the clustering) - for(int idxColBlock = 0 ; idxColBlock < nbPartitions ; ++idxColBlock){ - const MatrixClass::BlockDescriptor colBlock = matrix.getBlock(grid.getVBlockInfo(idxColBlock)); - int rj = -1; - /// TODO HERE - /// Compute rj, and the resulting Vj blocks, - /// use the colBlock (some or all of its values) - - /// TODO END - // Store the result in grid.getVBlock(idxColBlock) - CellClass& Vj = grid.getVBlock(idxColBlock); - Vj.resize(rj, colBlock.getNbCols()); - for(int idxRow = 0 ; idxRow < Vj.getNbRows() ; ++idxRow){ - for(int idxCol = 0 ; idxCol < Vj.getNbCols() ; ++idxCol){ - /// TODO HERE - /// Fill Vj with the result - Vj.setValue(idxRow, idxCol, -1); - /// TODO END - } - } - } - // U blocks cover all the columns, but only some rows (based on the clustering) - for(int idxRowBlock = 0 ; idxRowBlock < nbPartitions ; ++idxRowBlock){ - const MatrixClass::BlockDescriptor rowBlock = matrix.getBlock(grid.getUBlockInfo(idxRowBlock)); - int ri = -1; - /// TODO HERE - /// Compute ri, and the resulting Ui blocks - /// use the rowBlock (some or all of its values) - - /// TODO END - // Store the result in grid.getUBlock(idxRowBlock) - CellClass& Ui = grid.getUBlock(idxRowBlock); - Ui.resize(rowBlock.getNbRows(), ri); - for(int idxRow = 0 ; idxRow < Ui.getNbRows() ; ++idxRow){ - for(int idxCol = 0 ; idxCol < Ui.getNbCols() ; ++idxCol){ - /// TODO HERE - /// Fill Vj with the result - Ui.setValue(idxRow, idxCol, -1); - /// TODO END - } - } - } - // Build the core part - for(int idxColBlock = 0 ; idxColBlock < nbPartitions ; ++idxColBlock){ - for(int idxRowBlock = 0 ; idxRowBlock < nbPartitions ; ++idxRowBlock){ - const CellClass& Ui = grid.getUBlock(idxRowBlock); - const CellClass& Vj = grid.getVBlock(idxColBlock); - // Store the result in grid.getCBlock(idxRowBlock, idxColBlock) - CellClass& Cij = grid.getCBlock(idxRowBlock, idxColBlock); - Cij.resize(Vj.getNbRows(), Ui.getNbCols()); - for(int idxRow = 0 ; idxRow < Cij.getNbRows() ; ++idxRow){ - for(int idxCol = 0 ; idxCol < Cij.getNbCols() ; ++idxCol){ - /// TODO HERE - /// Fill Vj with the result - Cij.setValue(idxRow, idxCol, -1); - /// TODO END - } - } - } - } - - std::unique_ptr resDense(new FReal[dim]); - FSetToZeros(resDense.get(), dim); - - //grid.gemv(resDense.get(), vec.get()); - - FMath::FAccurater testDense(resTest.get(), resDense.get(), dim); - - std::cout << "Test Dense partitions mapping, Error = " << testDense << "\n"; - } - - return 0; -} - - - diff --git a/Addons/HMat/Tests/testSDB.cpp b/Addons/HMat/Tests/testSDB.cpp deleted file mode 100644 index 14e920bc3a23dfbbdef75fe4aeb02284e0b51d4c..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testSDB.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - - FHelpDescribeAndExit(argc, argv,"Test the bisection.",SvgOutParam,DimParam,FParameterDefinitions::OctreeHeight); - - const int dim = FParameters::getValue(argc, argv, DimParam.options, 100); - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 4); - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - - std::cout << "Config : dim = " << dim << "\n"; - std::cout << "Config : height = " << height << "\n"; - std::cout << "Config : outputdir = " << outputdir << "\n"; - - typedef double FReal; - typedef FDenseBlock LeafClass; - typedef FDenseBlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - { - GridClass bissection(dim, height); - - FSvgRect output(outputdir, "classic", dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - { - const int nbPartitions = FMath::pow2(height-1); - std::unique_ptr partitions(new int[nbPartitions]); - { - int nbValuesLeft = dim; - for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){ - partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition)))); - nbValuesLeft -= partitions[idxPartition]; - } - partitions[nbPartitions-1] = nbValuesLeft; - } - - GridClass bissection(dim, height, partitions.get(), nbPartitions); - - FSvgRect output(outputdir, "partitioned", dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - - return 0; -} diff --git a/Addons/HMat/Tests/testSDBGemv.cpp b/Addons/HMat/Tests/testSDBGemv.cpp deleted file mode 100644 index 6e6121ede30edba26bc3b9ed1654404b67dfa78d..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testSDBGemv.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Viewers/FMatDense.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include "Utils/FTic.hpp" - -#include - -int main(int argc, char** argv){ - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - - FHelpDescribeAndExit(argc, argv, "Test the bisection.", DimParam, FParameterDefinitions::OctreeHeight); - - //////////////////////////////////////////////////////////////////// - /// Timers - FTic time; - time.tic(); - - const int dim = FParameters::getValue(argc, argv, DimParam.options, 100); - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 4); - - std::cout << "Config : dim = " << dim << "\n"; - std::cout << "Config : height = " << height << "\n"; - - - typedef double FReal; - typedef FMatDense MatrixClass; - - MatrixClass matrix(dim); - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - matrix.setVal(idxRow, idxCol, 1./(FMath::Abs(FReal(idxRow-idxCol))+1.)); - } - } - - std::unique_ptr vec(new FReal[dim]); - for(int idxVal = 0 ; idxVal < dim ; ++idxVal){ - vec[idxVal] = 1.0; - } - - std::unique_ptr resTest(new FReal[dim]); - FSetToZeros(resTest.get(), dim); - { - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - resTest[idxRow] += vec[idxCol] * matrix.getVal(idxRow, idxCol); - } - } - } - - { - typedef FDenseBlock LeafClass; - typedef FDenseBlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - GridClass grid(dim, height); - grid.fillBlocks(matrix); - - std::unique_ptr resDense(new FReal[dim]); - FSetToZeros(resDense.get(), dim); - - grid.gemv(resDense.get(), vec.get()); - - FMath::FAccurater testDense(resTest.get(), resDense.get(), dim); - - std::cout << "Test Dense, Error = " << testDense << "\n"; - } - - { - typedef FDenseBlock LeafClass; - typedef FDenseBlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - const int nbPartitions = FMath::pow2(height-1); - std::unique_ptr partitions(new int[nbPartitions]); - { - int nbValuesLeft = dim; - for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){ - partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition)))); - nbValuesLeft -= partitions[idxPartition]; - } - partitions[nbPartitions-1] = nbValuesLeft; - } - - GridClass grid(dim, height, partitions.get(), nbPartitions); - grid.fillBlocks(matrix); - - std::unique_ptr resDense(new FReal[dim]); - FSetToZeros(resDense.get(), dim); - - grid.gemv(resDense.get(), vec.get()); - - FMath::FAccurater testDense(resTest.get(), resDense.get(), dim); - - std::cout << "Test Dense with partitions, Error = " << testDense << "\n"; - } - - double tOverall = time.tacAndElapsed(); - std::cout << "... took @tOverall = "<< tOverall <<"\n"; - - return 0; -} - diff --git a/Addons/HMat/Tests/testSDBGemvFile.cpp b/Addons/HMat/Tests/testSDBGemvFile.cpp deleted file mode 100644 index 6995a682291f0ae97d90e56f9628e7f7193971bc..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testSDBGemvFile.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// =================================================================================== -// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner -// olivier.coulaud@inria.fr, berenger.bramas@inria.fr -// This software is a computer program whose purpose is to compute the FMM. -// -// This software is governed by the CeCILL-C and LGPL licenses and -// abiding by the rules of distribution of free software. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public and CeCILL-C Licenses for more details. -// "http://www.cecill.info". -// "http://www.gnu.org/licenses". -// =================================================================================== - -// @SCALFMM_PRIVATE - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Viewers/FMatDense.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" -#include "../Src/Blocks/FSVDBlock.hpp" -#include "../Src/Blocks/FACABlock.hpp" - - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include "Utils/FTic.hpp" - -#include - -int main(int argc, char** argv){ - FHelpDescribeAndExit(argc, argv, "Test the bisection.", FParameterDefinitions::InputFile, FParameterDefinitions::OctreeHeight); - - //////////////////////////////////////////////////////////////////// - /// Timers - FTic time; - time.tic(); - - //const char* filename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFile.options, "../Addons/HMat/Data/unitCube1000_ONE_OVER_R.bin"); - const char* filename = FParameters::getStr(argc, argv, FParameterDefinitions::InputFile.options, "../Addons/HMat/Data/unitSphere1000_GAUSS100.bin"); - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 4); - - - typedef double FReal; - typedef FMatDense MatrixClass; - - MatrixClass matrix(filename); - const int dim = matrix.getDim(); - - std::cout << "Config : dim = " << dim << "\n"; - std::cout << "Config : height = " << height << "\n"; - - std::unique_ptr vec(new FReal[dim]); - for(int idxVal = 0 ; idxVal < dim ; ++idxVal){ - vec[idxVal] = 1.0; - } - - std::unique_ptr resTest(new FReal[dim]); - FSetToZeros(resTest.get(), dim); - { - for(int idxRow = 0; idxRow < dim ; ++idxRow){ - for(int idxCol = 0; idxCol < dim ; ++idxCol){ - resTest[idxRow] += vec[idxCol] * matrix.getVal(idxRow, idxCol); - } - } - } - - { - std::cout << "Test Dense leaves + Low rank cells:\n"; - typedef FDenseBlock LeafClass; - //typedef FDenseBlock CellClass; - typedef FSVDBlock CellClass; - //typedef FACABlock CellClass; - - typedef FStaticDiagonalBisection GridClass; - - GridClass grid(dim, height); - grid.fillBlocks(matrix); - - std::unique_ptr resDense(new FReal[dim]); - FSetToZeros(resDense.get(), dim); - - std::cout << " Perform GEMV "; - - FTic timeGEMV; - timeGEMV.tic(); - - grid.gemv(resDense.get(), vec.get()); - - double tGEMV = timeGEMV.tacAndElapsed(); - std::cout << "... took @tGEMV = "<< tGEMV <<"\n"; - - FMath::FAccurater testDense(resTest.get(), resDense.get(), dim); - - std::cout << " Error = " << testDense << "\n"; - } - - { - - std::cout << "Test Dense leaves + Low rank cells, with partitions:\n"; - - typedef FDenseBlock LeafClass; - //typedef FDenseBlock CellClass; - typedef FSVDBlock CellClass; - //typedef FACABlock CellClass; - - typedef FStaticDiagonalBisection GridClass; - - const int nbPartitions = FMath::pow2(height-1); - std::unique_ptr partitions(new int[nbPartitions]); - { - int nbValuesLeft = dim; - for(int idxPartition = 0 ; idxPartition < nbPartitions-1 ; ++idxPartition){ - partitions[idxPartition] = FMath::Max(1, int(drand48()*(nbValuesLeft-(nbPartitions-idxPartition)))); - nbValuesLeft -= partitions[idxPartition]; - } - partitions[nbPartitions-1] = nbValuesLeft; - } - - GridClass grid(dim, height, partitions.get(), nbPartitions); - grid.fillBlocks(matrix); - - std::unique_ptr resDense(new FReal[dim]); - FSetToZeros(resDense.get(), dim); - - std::cout << " Perform GEMV "; - - FTic timeGEMV; - timeGEMV.tic(); - - grid.gemv(resDense.get(), vec.get()); - - double tGEMV = timeGEMV.tacAndElapsed(); - std::cout << "... took @tGEMV = "<< tGEMV <<"\n"; - - FMath::FAccurater testDense(resTest.get(), resDense.get(), dim); - - std::cout << " Error = " << testDense << "\n"; - } - - double tOverall = time.tacAndElapsed(); - std::cout << "... took @tOverall = "<< tOverall <<"\n"; - - return 0; -} - - diff --git a/Addons/HMat/Tests/testSeeClustering.cpp b/Addons/HMat/Tests/testSeeClustering.cpp deleted file mode 100644 index 4ea4207d35f77b65a7a6149b0154221d1499623d..0000000000000000000000000000000000000000 --- a/Addons/HMat/Tests/testSeeClustering.cpp +++ /dev/null @@ -1,173 +0,0 @@ - -// @SCALFMM_PRIVATE - -#include "../Src/Clustering/FCCLTreeCluster.hpp" -#include "../Src/Clustering/FGraphThreshold.hpp" -#include "../Src/Clustering/FCCLTreeCluster.hpp" -#include "../Src/Clustering/FMaxDistCut.hpp" -#include "../Src/Utils/FMatrixIO.hpp" - -#include "../Src/Containers/FStaticDiagonalBisection.hpp" -#include "../Src/Utils/FSvgRect.hpp" -#include "../Src/Viewers/FDenseBlockWrapper.hpp" -#include "../Src/Blocks/FDenseBlock.hpp" - -#include "Utils/FParameters.hpp" -#include "Utils/FParameterNames.hpp" - -#include "Files/FGenerateDistribution.hpp" - -#include - -// FUSE_SCOTCH - -template -void TestPartitions(const PartitionerClass& partitioner, const int height, - const char outputdir[], const int dim, - const FReal coords[], const char config[]){ - FClusterTree tclusters; - partitioner.fillClusterTree(&tclusters); - tclusters.checkData(); - - { - char filenameBuffer[1024]; - sprintf(filenameBuffer, "%s/%s.xml", outputdir, config); - std::cout << "\t save xml to " << filenameBuffer << "\n"; - tclusters.saveToXml(filenameBuffer); - sprintf(filenameBuffer, "%s/%s.dot", outputdir, config); - std::cout << "\t save cdot to " << filenameBuffer << "\n"; - tclusters.saveToDot(filenameBuffer); - } - - std::unique_ptr permutations(new int[dim]); - std::unique_ptr invpermutations(new int[dim]); - tclusters.fillPermutations(permutations.get(), invpermutations.get()); - - for(int idxLevel = 2 ; idxLevel <= height ; ++idxLevel){ - const int nbPartitions = FMath::pow2(idxLevel-1); - std::unique_ptr partitions(new int[nbPartitions]); - tclusters.getPartitions(idxLevel, nbPartitions, partitions.get()); - - { - char coordfilename[1024]; - sprintf(coordfilename, "%s/%s-coord-%d.csv", outputdir, config, idxLevel); - std::cout << "\t save coord for level " << idxLevel << " to " << coordfilename << "\n"; - FILE* fcoord = fopen(coordfilename, "w"); - - int offsetParticles = 0; - for(int idxPartition = 0 ; idxPartition < nbPartitions ; ++idxPartition){ - for(int idxPart = 0 ; idxPart < partitions[idxPartition] ; ++idxPart){ - const int idxUnk = invpermutations[idxPart+offsetParticles]; - fprintf(fcoord, "%e,%e,%e,%d\n", - coords[idxUnk*4 + 0], - coords[idxUnk*4 + 1], - coords[idxUnk*4 + 2], - idxPartition); - } - offsetParticles += partitions[idxPartition]; - } - FAssertLF(offsetParticles == dim); - - fclose(fcoord); - } - { - typedef FDenseBlock LeafClass; - typedef FDenseBlock CellClass; - typedef FStaticDiagonalBisection GridClass; - - GridClass bissection(dim, idxLevel, partitions.get(), nbPartitions); - - char svgfilename[1024]; - sprintf(svgfilename, "%s/%s-%d.svg", outputdir, config, idxLevel); - std::cout << "\t save svg for level " << idxLevel << " to " << svgfilename << "\n"; - FSvgRect output(svgfilename, dim); - - bissection.forAllBlocksDescriptor([&](const FBlockDescriptor& info){ - output.addRectWithLegend(info.col, info.row, info.nbCols, info.nbRows, info.level); - }); - } - } -} - -int main(int argc, char** argv){ - static const FParameterNames SvgOutParam = { - {"-fout", "--out", "-out"} , - "Svg output directory." - }; - static const FParameterNames DimParam = { - {"-N", "-nb", "-dim"} , - "Dim of the matrix." - }; - - FHelpDescribeAndExit(argc, argv,"Test the bisection.",SvgOutParam,DimParam,FParameterDefinitions::OctreeHeight, - FParameterDefinitions::NbParticles); - - const int nbParticles = (FParameters::getValue(argc, argv, FParameterDefinitions::NbParticles.options, 3000) & ~1); - const int height = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 6); - const char* outputdir = FParameters::getStr(argc, argv, SvgOutParam.options, "/tmp/"); - - typedef double FReal; - - ///////////////////////////////////////////////////////////////// - - std::cout << "Create spheres\n"; - - const FReal radius = 0.5; - const FReal distanceBetweenSpheres = 0.4; - const int nbPointsSphere = nbParticles/2; - - std::cout << "\tradius = " << radius << "\n"; - std::cout << "\tdistanceBetweenSpheres = " << distanceBetweenSpheres << "\n"; - std::cout << "\tnbPointsSphere = " << nbPointsSphere << "\n"; - - std::unique_ptr spherePoints(new FReal[nbParticles*4]); - unifRandonPointsOnSphere(nbPointsSphere, radius, spherePoints.get()) ; - - for(int idxPoint = 0 ; idxPoint < nbPointsSphere ; ++idxPoint){ - spherePoints[(idxPoint+nbPointsSphere)*4 + 0] = spherePoints[idxPoint*4 + 0] + radius*2 + distanceBetweenSpheres; - spherePoints[(idxPoint+nbPointsSphere)*4 + 1] = spherePoints[idxPoint*4 + 1] + radius*2 + distanceBetweenSpheres; - spherePoints[(idxPoint+nbPointsSphere)*4 + 2] = spherePoints[idxPoint*4 + 2] + radius*2 + distanceBetweenSpheres; - } - - ///////////////////////////////////////////////////////////////// - - std::cout << "Compute distance\n"; - - const int dim = nbParticles; - std::unique_ptr distances(new FReal[nbParticles*nbParticles]); - for(int idxCol = 0 ; idxCol < nbParticles ; ++idxCol){ - for(int idxRow = 0 ; idxRow < nbParticles ; ++idxRow){ - const FReal diffx = spherePoints[idxCol*4 + 0] - spherePoints[idxRow*4 + 0]; - const FReal diffy = spherePoints[idxCol*4 + 1] - spherePoints[idxRow*4 + 1]; - const FReal diffz = spherePoints[idxCol*4 + 2] - spherePoints[idxRow*4 + 2]; - distances[idxCol*nbParticles+idxRow] = FMath::Sqrt((diffx*diffx) + (diffy*diffy) + (diffz*diffz)); - } - } - - ///////////////////////////////////////////////////////////////// - { - std::cout << "Test FGraphThreshold\n"; - FGraphThreshold partitioner(dim, distances.get(), radius/4); - TestPartitions>(partitioner,height, outputdir, - dim, spherePoints.get(), "FGraphThreshold"); - } - ///////////////////////////////////////////////////////////////// - { - std::cout << "Test FCCLTreeCluster\n"; - FCCLTreeCluster partitioner(dim, distances.get(), CCL::CCL_TM_MAXIMUM); - TestPartitions>(partitioner,height, outputdir, - dim, spherePoints.get(), "FCCLTreeCluster"); - } - ///////////////////////////////////////////////////////////////// - { - std::cout << "Test FMaxDistCut\n"; - FMaxDistCut partitioner(dim, distances.get()); - TestPartitions>(partitioner,height, outputdir, - dim, spherePoints.get(), "FMaxDistCut"); - } - - return 0; -} - - - diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cba9ff038a19f361ee3968f03dc8a3d76e66a9d..2d6eaa4222e5159309267f06d5b890161ce29971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ GetCpuInfos() # SCALFMM version number. An even minor number corresponds to releases. set(SCALFMM_MAJOR_VERSION 1) -set(SCALFMM_MINOR_VERSION 4) +set(SCALFMM_MINOR_VERSION 5) set(SCALFMM_PATCH_VERSION 0) set(SCALFMM_VERSION "${SCALFMM_MAJOR_VERSION}.${SCALFMM_MINOR_VERSION}.${SCALFMM_PATCH_VERSION}" ) @@ -53,6 +53,20 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ set(MORSE_CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse ) endif() include(MorseInit) + # Set the RPATH config + # -------------------- + # use, i.e. don't skip the full RPATH for the build tree + set(CMAKE_SKIP_BUILD_RPATH FALSE) + # when building, don't use the install RPATH already + # (but later on when installing) + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + # the RPATH to be used when installing + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") + + # Build ScalFmm as static or dynamic lib + # -------------------------------------- + option(BUILD_SHARED_LIBS "Build shared libraries" OFF) + # # Options # @@ -72,14 +86,14 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ option( SCALFMM_USE_SIGNALS "Set to ON to catch various signal an print backtrace" OFF ) option( SCALFMM_USE_ASSERT "Set to ON to enable safe tests during execution" ON ) option( SCALFMM_USE_MIC_NATIVE "Set to ON to compile in native mode for MIC" OFF ) - option( SCALFMM_ONLY_DEVEL "Set to ON to compile Development tools (only scalfmm team)" ON ) + option( SCALFMM_ONLY_DEVEL "Set to ON to compile Development tools (only scalfmm team)" OFF ) option( SCALFMM_USE_EZTRACE "Set to ON to compile with eztrace framwork" OFF ) option( SCALFMM_USE_STARPU "Set to ON to build SCALFMM with StarPU" OFF ) option( SCALFMM_BUILD_UTILS "Set to ON to build utils Tests" OFF ) -# -# VECTORISATION -# + # + # VECTORISATION + # if( APPLE ) # to fix problem with GCC and avx CMAKE_DEPENDENT_OPTION( SCALFMM_USE_SSE "Set to ON to compile with SSE support (and use intrinsec SSE P2P)" ON "CPUOPTION_SSE3;NOT CPUOPTION_AVX2" OFF ) CMAKE_DEPENDENT_OPTION( SCALFMM_USE_AVX "Set to ON to compile with AVX support (and use intrinsec AVX P2P)" OFF "CPUOPTION_AVX; NOT CPUOPTION_AVX2" OFF ) @@ -90,11 +104,15 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ CMAKE_DEPENDENT_OPTION( SCALFMM_USE_AVX2 "Set to ON to compile with AVX support (and use intrinsec AVX2 P2P)" ON "CPUOPTION_AVX2" OFF ) if( SCALFMM_ONLY_DEVEL ) -# OPENMP 4/5 support + # OPENMP 4/5 support option( OPENMP_SUPPORT_COMMUTE "Set to ON to let tasks commute (KSTAR/StarPU compiler only)" OFF ) option( OPENMP_SUPPORT_PRIORITY "Set to ON to enable tasks priority (KSTAR/StarPU compiler only)" OFF ) option( OPENMP_SUPPORT_TASK_NAME "Set to ON to enable a taskname clause for tasks (KSTAR/StarPU compiler only)" OFF ) - option( SCALFMM_DISABLE_NATIVE_OMP4 "Set to ON to disable the gcc/intel omp4" OFF ) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + option( SCALFMM_DISABLE_NATIVE_OMP4 "Set to ON to disable the gcc/intel omp4" OFF ) + else() + option( SCALFMM_DISABLE_NATIVE_OMP4 "Set to ON to disable the gcc/intel omp4" ON ) + endif() option( SCALFMM_TIME_OMPTASKS "Set to ON to time omp4 tasks and generate output file" OFF ) # SIMGRID and peformance models options option( SCALFMM_SIMGRID_NODATA "Set to ON to avoid the allocation of numerical parts in the group tree" OFF ) @@ -106,9 +124,9 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ CMAKE_DEPENDENT_OPTION(SCALFMM_STARPU_FORCE_NO_SCHEDULER "Set to ON to disable heteroprio even if supported" OFF "SCALFMM_USE_STARPU" OFF) endif() message(STATUS "AVANT ${CMAKE_CXX_COMPILER_ID}" ) -# -# MPI -# + # + # MPI + # if( SCALFMM_USE_MPI ) try_compile(COMPILE_INTEL ${CMAKE_CURRENT_BINARY_DIR} ${SCALFMM_CMAKE_MODULE_PATH}/compileTestIntel.cpp @@ -158,7 +176,9 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ set(SSE_FLAGS "-axSSE4.2 -march=native") endif(APPLE) #-Wshadow -Wpointer-arith -Wcast-qual -Wconversion -Wall -Wnosign-conversion ") - else() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "XL") + set(SCALFMM_CXX_FLAGS "${SCALFMM_CXX_FLAGS} -mcpu=power8 -mtune=power8") + else() #if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # NOT INTEL if(NOT SCALFMM_USE_MPI) include(CheckCCompilerFlag) @@ -244,8 +264,8 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ #set(SCALFMM_FLAGS_OPTI_RELEASE "-fp-model precise -fp-model source -fimf-precision=low -funroll-loops -ftree-vectorize" set(SCALFMM_FLAGS_OPTI_RELEASE "-funroll-loops -ftree-vectorize" CACHE STRING "Set your optimization flags for release mode.") - # set(SCALFMM_FLAGS_OPTI_RELEASE "-funroll-loops -ftree-vectorize" CACHE STRING - # "Set your optimization flags for release mode.") + # set(SCALFMM_FLAGS_OPTI_RELEASE "-funroll-loops -ftree-vectorize" CACHE STRING + # "Set your optimization flags for release mode.") else() set(SCALFMM_FLAGS_OPTI_RELEASE "-ffast-math -funroll-loops -ftree-vectorize" CACHE STRING "Set your optimization flags for release mode.") @@ -308,24 +328,37 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ ############################################################################## # if( SCALFMM_USE_BLAS ) + # include(FortranCInterface) + # # Define a Fortran interface file (FCMangle.hpp) + # FortranCInterface_HEADER( ${CMAKE_CURRENT_SOURCE_DIR}/Src/FCMangle.hpp + # MACRO_NAMESPACE "PM_" + # SYMBOL_NAMESPACE "PM_" + # SYMBOLS init testPPM:init) message(STATUS "CMAKE_CXX_COMPILER_ID STREQUAL ${CMAKE_CXX_COMPILER_ID}") - option( SCALFMM_USE_MKL_AS_BLAS "Set to ON to use MKL CBLAS" OFF ) + option( SCALFMM_USE_MKL_AS_BLAS "Set to ON to use MKL BLAS/LAPACK" OFF ) + option( SCALFMM_USE_ESSL_AS_BLAS "Set to ON to use ESSL BLAS/LAPACK" OFF ) if( SCALFMM_USE_MKL_AS_BLAS ) set(BLA_VENDOR "Intel10_64lp_seq") find_package(BLASEXT QUIET) # not REQUIRED - - if(BLAS_LIBRARY_DIRS) - # the RPATH to be used when installing - list(APPEND CMAKE_INSTALL_RPATH "${BLAS_LIBRARY_DIRS}") - endif() unset(LAPACK_LIBRARIES) if (BLAS_LIBRARIES) set(BLASLAPACK_LIBRARIES ${BLAS_LIBRARIES}) endif() + elseif(SCALFMM_USE_ESSL_AS_BLAS) + set(BLA_VENDOR "IBMESSL") + find_package(BLASEXT QUIET) # not REQUIRED + find_package(LAPACKEXT QUIET) # not REQUIRED + if (LAPACK_LIBRARIES) + set(BLASLAPACK_LIBRARIES "${LAPACK_LIBRARIES}") + endif() + if (BLAS_LIBRARIES) + list(APPEND BLASLAPACK_LIBRARIES ${BLAS_LIBRARIES}) + endif() elseif(SCALFMM_USE_EXTERNAL_BLAS) message(STATUS "BLAS SET BY EXTERNAL PROGRAM = ${BLAS_LIBRARIES}") + list(APPEND BLASLAPACK_LIBRARIES "${BLAS_LIBRARIES}") else() find_package(BLASEXT) # not REQUIRED find_package(LAPACKEXT) # not REQUIRED @@ -340,7 +373,62 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ if(BLAS_FOUND) set(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};${BLASLAPACK_LIBRARIES}") - #message(STATUS "SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") + if(BLAS_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${BLAS_LIBRARY_DIRS}") + endif() + if(LAPACK_FOUND AND LAPACK_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${LAPACK_LIBRARY_DIRS}") + endif() + message (STATUS "check BLAS Fortran mangling") + # add options to let the user be able to force a behavior + option( SCALFMM_BLAS_ADD_ "Set to ON to force calls to BLAS Fortran symbols with _ (ex: dgemm_)" OFF ) + option( SCALFMM_BLAS_UPCASE "Set to ON to force calls to BLAS Fortran symbols in capital (ex: DGEMM)" OFF ) + option( SCALFMM_BLAS_NOCHANGE "Set to ON to force calls to BLAS Fortran symbols with no change (ex: dgemm)" OFF ) + # if options not changed by user then auto-detection + if (NOT SCALFMM_BLAS_ADD_ AND NOT SCALFMM_BLAS_UPCASE AND NOT SCALFMM_BLAS_NOCHANGE) + # give blas libraries and check dgemm symbol + set(CMAKE_REQUIRED_LIBRARIES "${BLAS_LIBRARIES}") + check_function_exists(dgemv_ DGEMV_ADD_) + check_function_exists(DGEMV DGEMV_UPCASE) + check_function_exists(dgemv DGEMV_NOCHANGE) + # here we consider that the first kind of symbol found will be the one used + # current order is: ADD_, UPCASE, NOCHANGE + if (DGEMV_ADD_) + set (SCALFMM_BLAS_ADD_ ON) + set (SCALFMM_BLAS_UPCASE OFF) + set (SCALFMM_BLAS_NOCHANGE OFF) + message (STATUS "BLAS dgemv_ symbol found, SCALFMM_BLAS_ADD_ is ON") + else (DGEMV_ADD_) + if (DGEMV_UPCASE) + set (SCALFMM_BLAS_ADD_ OFF) + set (SCALFMM_BLAS_UPCASE ON) + set (SCALFMM_BLAS_NOCHANGE OFF) + message (STATUS "BLAS DGEMV symbol found, SCALFMM_BLAS_UPCASE is ON") + else (DGEMV_UPCASE) + if (DGEMV_NOCHANGE) + set (SCALFMM_BLAS_ADD_ OFF) + set (SCALFMM_BLAS_UPCASE OFF) + set (SCALFMM_BLAS_NOCHANGE ON) + message (STATUS "BLAS dgemv symbol found, SCALFMM_BLAS_NOCHANGE is ON") + endif (DGEMV_NOCHANGE) + endif (DGEMV_UPCASE) + endif (DGEMV_ADD_) + if ( (NOT DGEMV_ADD_) AND (NOT DGEMV_UPCASE) AND (NOT DGEMV_NOCHANGE) ) + message(FATAL_ERROR "BLAS Fortran mangling is not properly detected - please check your BLAS libraries") + endif () + else (NOT SCALFMM_BLAS_ADD_ AND NOT SCALFMM_BLAS_UPCASE AND NOT SCALFMM_BLAS_NOCHANGE) + if (SCALFMM_BLAS_ADD_) + message (STATUS "SCALFMM_BLAS_ADD_ is set to ON") + endif() + if (SCALFMM_BLAS_UPCASE) + message (STATUS "SCALFMM_BLAS_UPCASE is set to ON") + endif() + if (SCALFMM_BLAS_NOCHANGE) + message (STATUS "SCALFMM_BLAS_NOCHANGE is set to ON") + endif() + endif (NOT SCALFMM_BLAS_ADD_ AND NOT SCALFMM_BLAS_UPCASE AND NOT SCALFMM_BLAS_NOCHANGE) else() message(WARNING "BLAS has not been found, SCALFMM will continue to compile but some applications will be disabled.") message(WARNING "If you have BLAS set BLAS_LIBDIR, BLAS_INCDIR or BLAS_DIR (CMake variables using -D or environment variables).") @@ -352,84 +440,63 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ # # FFT option # - CMAKE_DEPENDENT_OPTION(SCALFMM_USE_MKL_AS_FFTW "Set to ON to use MKL FFTW" ON "SCALFMM_USE_FFT;SCALFMM_USE_MKL_AS_BLAS" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_USE_MKL_AS_FFTW "Set to ON to use MKL FFTW" ON "SCALFMM_USE_FFT;SCALFMM_USE_MKL_AS_BLAS" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_USE_ESSL_AS_FFTW "Set to ON to use ESSL FFTW" ON "SCALFMM_USE_FFT;SCALFMM_USE_ESSL_AS_BLAS" OFF ) if( SCALFMM_USE_FFT ) message(STATUS "SCALFMM USE FFT Configure:") + # The package find_package(FFTW) can be used with the following COMPONENTS: + # MKL, ESSL, THREADS|OMP and/or SIMPLE|LONG|QUAD + # Default will find the real double precision fftw library version without THREADS|OMP if( SCALFMM_USE_MKL_AS_FFTW ) + message(STATUS " SCALFMM USE FFT from MKL") + find_package(FFTW COMPONENTS MKL) + elseif (SCALFMM_USE_ESSL_AS_FFTW) + message(STATUS " SCALFMM USE FFT from ESSL ") + find_package(FFTW COMPONENTS ESSL) + add_definitions(-DSCALFMM_USE_ESSL_AS_FFTW) + else() + message(STATUS " SCALFMM USE FFTW") + find_package(FFTW COMPONENTS SIMPLE) + endif() - message(STATUS " SCALFMM USE MKL ") - - if( SCALFMM_USE_MKL_AS_BLAS ) - - unset(FFT_LIBRARIES CACHE) - message(STATUS " SCALFMM USE MKL already defined") - set(FFT_INCLUDES "$ENV{MKLROOT}/include/fftw" CACHE STRING "Set your MKL flags") - if (BLAS_FOUND) - set(FFTW_FOUND ON) - endif() - - else(SCALFMM_USE_MKL_AS_BLAS) - - # The package can be used with the following COMPONENTS: - # MKL, THREADS|OMP and/or SIMPLE|DOUBLE|LONG|QUAD - # Default is DOUBLE and without THREADS|OMP - find_package(FFTW COMPONENTS MKL) # not REQUIRED - if (FFTW_LIBRARY_DIRS_DEP) - set(FFT_LIBRARIES "-L${FFTW_LIBRARY_DIRS_DEP};" CACHE STRING "Set your MKL flags") - endif() - if (FFTW_LIBRARIES_DEP) - foreach (fft_lib ${FFTW_LIBRARIES_DEP}) - set(FFT_LIBRARIES "${FFT_LIBRARIES};${fft_lib};") - endforeach() - endif() - set(FFT_INCLUDES "${FFTW_INCLUDE_DIRS_DEP}" ) - if (FFT_LIBRARIES) - set(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};${FFT_LIBRARIES}") - endif() - - endif(SCALFMM_USE_MKL_AS_BLAS) - - else(SCALFMM_USE_MKL_AS_FFTW) - - message(STATUS " SCALFMM USE FFTW ") - # The package can be used with the following COMPONENTS: - # MKL, THREADS|OMP and/or SIMPLE|DOUBLE|LONG|QUAD - # Default is DOUBLE and without THREADS|OMP - find_package(FFTW COMPONENTS SIMPLE) # not REQUIRED - if (FFTW_LIBRARY_DIRS_DEP) - set(FFT_LIBRARIES "-L${FFTW_LIBRARY_DIRS_DEP};" CACHE STRING "Set your FFTW path") - endif() - if (FFTW_LIBRARIES_DEP) - foreach (fft_lib ${FFTW_LIBRARIES_DEP}) - set(FFT_LIBRARIES "${FFT_LIBRARIES};${fft_lib};") - endforeach() - endif() - set(FFT_INCLUDES "${FFTW_INCLUDE_DIRS_DEP}" ) - if (FFT_LIBRARIES) - set(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};${FFT_LIBRARIES}") - endif() + if (FFTW_LIBRARY_DIRS_DEP) + set(FFT_LIBRARIES "-L${FFTW_LIBRARY_DIRS_DEP};" CACHE STRING "Set your MKL flags") + endif() + if (FFTW_LIBRARIES_DEP) + foreach (fft_lib ${FFTW_LIBRARIES_DEP}) + set(FFT_LIBRARIES "${FFT_LIBRARIES};${fft_lib};") + endforeach() + endif() - endif(SCALFMM_USE_MKL_AS_FFTW) + set(FFT_INCLUDES "${FFTW_INCLUDE_DIRS_DEP}" ) + if (FFT_LIBRARIES) + set(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};${FFT_LIBRARIES}") + endif() + if(FFTW_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${FFTW_LIBRARY_DIRS}") + endif() if (FFT_INCLUDES) set(SCALFMM_INCLUDES "${SCALFMM_INCLUDES}; ${FFT_INCLUDES}") endif() - if(FFTW_FOUND) - message(STATUS " SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") - message(STATUS " SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}") - else() + if(NOT FFTW_FOUND) message(WARNING "FFTW has not been found, SCALFMM will continue to compile but some applications will be disabled.") message(WARNING "If you have FFTW set FFTW_LIBDIR, FFTW_INCDIR or FFTW_DIR (CMake variables using -D or environment variables).") set(SCALFMM_USE_FFT OFF) endif() + endif(SCALFMM_USE_FFT) list(APPEND FUSE_LIST "FFT") - message(STATUS " SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") - message(STATUS " SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}") - message(STATUS "SCALFMM_USE_FFT = ${SCALFMM_USE_FFT}") + if (SCALFMM_INCLUDES) + list(REMOVE_DUPLICATES SCALFMM_INCLUDES) + endif() + if (SCALFMM_LIBRARIES) + list(REMOVE_DUPLICATES SCALFMM_LIBRARIES) + endif() # # C++ 2011 @@ -473,7 +540,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ if (CUDA_LIBRARIES) set(SCALFMM_LIBRARIES "${SCALFMM_LIBRARIES};${CUDA_LIBRARIES}") endif() - + set(CUDA_NEEDED_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/Src) endif() @@ -491,6 +558,19 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ find_package(STARPU ${SCALFMM_STARPU_VERSION} REQUIRED COMPONENTS ${STARPU_COMPONENT_LIST}) + if(HWLOC_FOUND AND HWLOC_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${HWLOC_LIBRARY_DIRS}") + endif() + if(FXT_FOUND AND FXT_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${FXT_LIBRARY_DIRS}") + endif() + if(STARPU_FOUND AND STARPU_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${STARPU_LIBRARY_DIRS}") + endif() + # Append list of libraries and include dirs include_directories(${STARPU_INCLUDE_DIRS_DEP}) foreach (starpu_libdir ${STARPU_LIBRARY_DIRS_DEP}) @@ -583,7 +663,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ OUTPUT_VARIABLE COMPILE_AVX_OUTPUT) if(${COMPILE_AVX}) message(STATUS "%%%%%%%%%%%% COMPILE_AVX = ${COMPILE_AVX} %%%%< ${AVX_FLAGS}") - + set(SCALFMM_CXX_FLAGS "${SCALFMM_CXX_FLAGS} ${AVX_FLAGS}") message(STATUS "%%%%%%%%%%%% SCALFMM_CXX_FLAGS = ${SCALFMM_CXX_FLAGS}") #set( SCALFMM_USE_SSE OFF FORCE) # ne marche pas @@ -671,20 +751,24 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ if(EZTrace_FOUND) link_directories(${EZTrace_LIBRARY_DIRS}) link_libraries( ${EZTrace_LIBRARIES}) + if (EZTrace_LIBRARY_DIRS) + # the RPATH to be used when installing + list(APPEND CMAKE_INSTALL_RPATH "${EZTrace_LIBRARY_DIRS}") + endif() IF( SCALFMM_USE_MPI ) link_libraries(-leztrace-autostart-mpi) - ENDIF(SCALFMM_USE_MPI) - include_directories(${EZTrace_INCLUDE_DIRS}) - MESSAGE(STATUS "EZTRACE: ${EZTrace_INCLUDE_DIRS} ${EZTrace_LIBRARY_DIRS} ${EZTrace_LIBRARIES}") - CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_ALGO "Set to ON to trace the full algorithm (all operators)" ON "SCALFMM_USE_EZTRACE" OFF ) - CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_P2M "Set to ON to trace P2M operator" OFF "SCALFMM_USE_EZTRACE" OFF ) - CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_M2M "Set to ON to trace M2M operator" OFF "SCALFMM_USE_EZTRACE" OFF ) - CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_M2L "Set to ON to trace M2L operator" OFF "SCALFMM_USE_EZTRACE" OFF ) - CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_L2L "Set to ON to trace L2L operator" OFF "SCALFMM_USE_EZTRACE" OFF ) - CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_P2P "Set to ON to trace P2P operator" OFF "SCALFMM_USE_EZTRACE" OFF ) + ENDIF(SCALFMM_USE_MPI) + include_directories(${EZTrace_INCLUDE_DIRS}) + MESSAGE(STATUS "EZTRACE: ${EZTrace_INCLUDE_DIRS} ${EZTrace_LIBRARY_DIRS} ${EZTrace_LIBRARIES}") + CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_ALGO "Set to ON to trace the full algorithm (all operators)" ON "SCALFMM_USE_EZTRACE" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_P2M "Set to ON to trace P2M operator" OFF "SCALFMM_USE_EZTRACE" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_M2M "Set to ON to trace M2M operator" OFF "SCALFMM_USE_EZTRACE" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_M2L "Set to ON to trace M2L operator" OFF "SCALFMM_USE_EZTRACE" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_L2L "Set to ON to trace L2L operator" OFF "SCALFMM_USE_EZTRACE" OFF ) + CMAKE_DEPENDENT_OPTION(SCALFMM_TRACE_P2P "Set to ON to trace P2P operator" OFF "SCALFMM_USE_EZTRACE" OFF ) else(EZTrace_FOUND) - MESSAGE(WARNING "Eztrace not found - EZTRACE Is set to OFF") - set(SCALFMM_USE_EZTRACE OFF) + MESSAGE(WARNING "Eztrace not found - EZTRACE Is set to OFF") + set(SCALFMM_USE_EZTRACE OFF) endif(EZTrace_FOUND) else(PKG_CONFIG_FOUND) MESSAGE(WARNING "PKG-CONFIG not found - EZTRACE Is set to OFF") @@ -692,21 +776,20 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ endif(PKG_CONFIG_FOUND) endif(SCALFMM_USE_EZTRACE) - + ################################################################## # # To catch signals # ################################################################## - if((WIN32 OR (${CMAKE_SYSTEM_NAME} MATCHES "Windows")) AND SCALFMM_USE_SIGNALS) - # We are on Windows and we cannot catch signals - message( FATAL_ERROR "Catching the signals requieres an UNIX system." ) - else() - IF( NOT APPLE) - SET(SCALFMM_CXX_FLAGS "${SCALFMM_CXX_FLAGS} -rdynamic") - ENDIF() - - endif() + if((WIN32 OR (${CMAKE_SYSTEM_NAME} MATCHES "Windows")) AND SCALFMM_USE_SIGNALS) + # We are on Windows and we cannot catch signals + message( FATAL_ERROR "Catching the signals requieres an UNIX system." ) + else() + IF( NOT APPLE) + SET(SCALFMM_CXX_FLAGS "${SCALFMM_CXX_FLAGS} -rdynamic") + ENDIF() + endif() ################################################################## # # # END SETTING VARIABLES # @@ -721,7 +804,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ set(SCALFMM_COMPILE_LIBS "") foreach(lib_var ${SCALFMM_LIBRARIES}) string(STRIP ${lib_var} lib_var) - LIST(APPEND SCALFMM_COMPILE_LIBS ${lib_var}) + LIST(APPEND SCALFMM_COMPILE_LIBS ${lib_var}) endforeach() configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/Src/ScalFmmConfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/Src/ScalFmmConfig.h ) @@ -737,7 +820,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ ################################################################## # Remove compilation of the drivers # ################################################################## - message(STATUS "SCALFMM_BUILD_EXAMPLES = ${SCALFMM_BUILD_EXAMPLES}" ) + message(STATUS "SCALFMM_BUILD_EXAMPLES = ${SCALFMM_BUILD_EXAMPLES}" ) if( SCALFMM_BUILD_EXAMPLES ) # Build - Examples and drivers add_subdirectory(Examples) @@ -769,13 +852,16 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ enable_testing() add_subdirectory(UTests) endif() - + # ################################################################## # Add - doc # ################################################################## + # + message(STATUS "SCALFMM_BUILD_DOC = ${SCALFMM_BUILD_DOC}" ) if(SCALFMM_BUILD_DOC) add_subdirectory(Doc) endif() + # ################################################################## # Build - Addons # ################################################################## @@ -816,7 +902,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ if( SCALFMM_INSTALL_DATA ) install(FILES ${SCALFMM_SOURCE_DIR}/Data/test20k.fma DESTINATION Data/ ) endif() - + # ################################################################## # # # build a CPack driven installer package # @@ -841,10 +927,10 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ set(PACK_PACKAGE_VERSION "${SCALFMM_MAJOR_VERSION}.${SCALFMM_MINOR_VERSION}-${CPACK_PACKAGE_VERSION_PATCH}") set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_PACKAGE_FILE_NAME "SCALFMM-${SCALFMM_MAJOR_VERSION}.${SCALFMM_MINOR_VERSION}-${CPACK_PACKAGE_VERSION_PATCH}") - set(CPACK_SOURCE_IGNORE_FILES "\\\\.git;.DS_Store;.*~;/*.aux;/*.idx;/*.log;/*.out;/*.toc;/*.ilg;scalfmm.pro*;org.eclipse.core.resources.prefs;.cproject;.project") - list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/Utils/;Notes;Deprecated;/Build*;/noDist/;/Bench;ToRemove;Olivier;Addons/HMat") + set(CPACK_SOURCE_IGNORE_FILES "\\\\.git;.DS_Store;.*~;/*.aux;/*.idx;/*.log;/*.out;/*.toc;/*.ilg;scalfmm.pro*;org.eclipse.core.resources.prefs;.cproject;.project;/.settings/,/FmmApi/") + list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}/Utils/;Notes;Deprecated;/Build*;/noDist/;/Bench/;/Obsolete/;ToRemove;Olivier;Addons/HMat") # Uniform;GroupTree;Adaptive;testUnif*;/*Lagrange*") - #list(APPEND CPACK_SOURCE_IGNORE_FILES "Stages;Uniform;Adaptive;testUnif*;*Lagrange*" ) + #list(APPEND CPACK_SOURCE_IGNORE_FILES "Stages;Uniform;O;testUnif*;*Lagrange*" ) # include(CPack) # @@ -854,30 +940,29 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/ # PRINT messages # # # ################################################################## - message(STATUS "CPACK_SOURCE_IGNORE_FILES = ${CPACK_SOURCE_IGNORE_FILES}") + message(STATUS "CPACK_SOURCE_IGNORE_FILES = ${CPACK_SOURCE_IGNORE_FILES}") message(STATUS "CPACK_SOURCE_PACKAGE_FILE_NAME = ${CPACK_SOURCE_PACKAGE_FILE_NAME}") # # Use Mem stats - message(STATUS "SCALFMM_USE_MEM_STATS = ${SCALFMM_USE_MEM_STATS}" ) + message(STATUS "SCALFMM_USE_MEM_STATS = ${SCALFMM_USE_MEM_STATS}" ) # Use Log - message(STATUS "SCALFMM_USE_LOG = ${SCALFMM_USE_LOG}" ) + message(STATUS "SCALFMM_USE_LOG = ${SCALFMM_USE_LOG}" ) # Use Assert - message(STATUS "SCALFMM_USE_ASSERT = ${SCALFMM_USE_ASSERT}" ) + message(STATUS "SCALFMM_USE_ASSERT = ${SCALFMM_USE_ASSERT}" ) # - #message(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") - #set(CMAKE_CXX_FLAGS "${SCALFMM_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") - message(STATUS "SCALFMM_USE_BLAS = ${SCALFMM_USE_BLAS}") + message(STATUS "SCALFMM_USE_BLAS = ${SCALFMM_USE_BLAS}") message(STATUS "SCALFMM_USE_FFT = ${SCALFMM_USE_FFT}") - message(STATUS "SCALFMM_USE_MKL = ${SCALFMM_USE_MKL}") + message(STATUS "SCALFMM_USE_MKL = ${SCALFMM_USE_MKL}") # - message(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") - message(STATUS "SCALFMM_CXX_FLAGS = ${SCALFMM_CXX_FLAGS}") - message(STATUS "SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") - message(STATUS "SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}") + message(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") + message(STATUS "SCALFMM_CXX_FLAGS = ${SCALFMM_CXX_FLAGS}") + message(STATUS "SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") + message(STATUS "SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}") + # ################################################################## # END # ################################################################## - + # else(MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/morse/") message(STATUS "MORSE_DISTRIB_DIR is not set") diff --git a/CMakeModules/getCpuInfos.cpp b/CMakeModules/getCpuInfos.cpp index 44bc19eafe435412b76f438fe4481f6d54c39ca3..4cbd3143cb373f01739af20ec4d7ea13c8389495 100644 --- a/CMakeModules/getCpuInfos.cpp +++ b/CMakeModules/getCpuInfos.cpp @@ -34,6 +34,8 @@ enum RegistersNum { // we would like to have the same name for not windows #define cpuid __cpuid +#elif _ARCH_PPC +#error("PPC") #else // Else we have to ask the CPU directly by executin cpuid. @@ -75,7 +77,7 @@ void cpuid(int CPUInfo[4],int InfoType){ #endif - +#ifndef _ARCH_PPC bool CPUInfoGetEAX(const int CPUInfo[4], const int position){ return (CPUInfo[EaxRegister] & ((int)1 << position)) != 0; } @@ -309,6 +311,9 @@ std::list getProperties(){ return properties; } +#else +// POWER (IBM) +#endif /////////////////////////////////////////////////////////////////////////// diff --git a/CMakeModules/morse/AuxilaryFlags.cmake b/CMakeModules/morse/AuxilaryFlags.cmake index 9b15b0f33ddf639a35d1a25fefab722f7f056534..9744d578b6eada54ef12355b27d1ff3000da2fb9 100644 --- a/CMakeModules/morse/AuxilaryFlags.cmake +++ b/CMakeModules/morse/AuxilaryFlags.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -20,20 +20,72 @@ # # @version 0.9.0 # @author Xavier Lacoste +# @author Florent Pruvost # @date 30-01-2015 # -# Define auxilary variables: +# Update CMAKE auxilary variables: +# - CMAKE_C_FLAGS: C compiler flags +# - CMAKE_CXX_FLAGS: CXX compiler flags +# - CMAKE_Fortran_FLAGS: Fortran compiler flags # - CMAKE_Fortran_PREPROCESS_FLAGS : force C preprocessor. # - CMAKE_Fortran_FREEFORM_FLAG : Force free format. -# - CMAKE_Fortran ### +if (MORSE_ENABLE_WARNING) -IF(CMAKE_Fortran_COMPILER_ID MATCHES GNU) + if(CMAKE_C_COMPILER_ID MATCHES GNU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + elseif(CMAKE_C_COMPILER_ID MATCHES Intel) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w3 -diag-disable:remark") + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES GNU) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w3 -diag-disable:remark") + endif() + + if(CMAKE_Fortran_COMPILER_ID MATCHES GNU) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wall") + elseif(CMAKE_Fortran_COMPILER_ID MATCHES Intel) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all -diag-disable:remark") + endif() + +endif(MORSE_ENABLE_WARNING) + +if (MORSE_ENABLE_COVERAGE) + + if(CMAKE_C_COMPILER_ID MATCHES GNU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") + else() + message(FATAL_ERROR "Code coverage is only available with the GNU C (gcc)" + "\n compiler, please turn MORSE_ENABLE_COVERAGE OFF\n.") + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES GNU) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + else() + message(FATAL_ERROR "Code coverage is only available with the GNU CXX" + "\n (g++) compiler, please turn MORSE_ENABLE_COVERAGE OFF\n.") + endif() + + if(CMAKE_Fortran_COMPILER_ID MATCHES GNU) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} --coverage") + else() + message(FATAL_ERROR "Code coverage is only available with the GNU" + "\n Fortran (gfortran) compiler, please turn MORSE_ENABLE_COVERAGE" + "\n OFF\n.") + endif() + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + +endif(MORSE_ENABLE_COVERAGE) + + +if(CMAKE_Fortran_COMPILER_ID MATCHES GNU) list(APPEND CMAKE_Fortran_PREPROCESS_FLAGS "-cpp") list(APPEND CMAKE_Fortran_FREEFORM_FLAG "-ffree-form") - -ELSEIF(CMAKE_Fortran_COMPILER_ID MATCHES Intel) +elseif(CMAKE_Fortran_COMPILER_ID MATCHES Intel) list(APPEND CMAKE_Fortran_PREPROCESS_FLAG "-fpp") list(APPEND CMAKE_Fortran_FREEFORM_FLAG "") -ENDIF() +endif() diff --git a/CMakeModules/morse/FindHeadersAndLibs.cmake b/CMakeModules/morse/FindHeadersAndLibs.cmake index 0f5eadde7b0618cc20e65feab12de5982b2fe3cc..d0919dcb001d66f04f9691f7a826037c7cec2e88 100644 --- a/CMakeModules/morse/FindHeadersAndLibs.cmake +++ b/CMakeModules/morse/FindHeadersAndLibs.cmake @@ -37,60 +37,60 @@ include(PrintFindStatus) function(FindHeader _libname _header_to_find) - # save _libname upper and lower case - string(TOUPPER ${_libname} LIBNAME) - string(TOLOWER ${_libname} libname) + # save _libname upper and lower case + string(TOUPPER ${_libname} LIBNAME) + string(TOLOWER ${_libname} libname) - # Looking for include - # ------------------- + # Looking for include + # ------------------- - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) - # Try to find the _header_to_find in the given paths - # -------------------------------------------------- - # call cmake macro to find the header path - if(${LIBNAME}_INCDIR) - set(${LIBNAME}_${_header_to_find}_DIRS "${LIBNAME}_${_header_to_find}_DIRS-NOTFOUND") - find_path(${LIBNAME}_${_header_to_find}_DIRS - NAMES ${_header_to_find} - HINTS ${${LIBNAME}_INCDIR}) - elseif(${LIBNAME}_DIR) - set(${LIBNAME}_${_header_to_find}_DIRS "${LIBNAME}_${_header_to_find}_DIRS-NOTFOUND") - find_path(${LIBNAME}_${_header_to_find}_DIRS - NAMES ${_header_to_find} - HINTS ${${LIBNAME}_DIR} - PATH_SUFFIXES include) - else() - set(${LIBNAME}_${_header_to_find}_DIRS "${LIBNAME}_${_header_to_find}_DIRS-NOTFOUND") - find_path(${LIBNAME}_${_header_to_find}_DIRS - NAMES ${_header_to_find} - HINTS ${_inc_env}) - endif() - mark_as_advanced(${LIBNAME}_${_header_to_find}_DIRS) + # Try to find the _header_to_find in the given paths + # -------------------------------------------------- + # call cmake macro to find the header path + if(${LIBNAME}_INCDIR) + set(${LIBNAME}_${_header_to_find}_DIRS "${LIBNAME}_${_header_to_find}_DIRS-NOTFOUND") + find_path(${LIBNAME}_${_header_to_find}_DIRS + NAMES ${_header_to_find} + HINTS ${${LIBNAME}_INCDIR}) + elseif(${LIBNAME}_DIR) + set(${LIBNAME}_${_header_to_find}_DIRS "${LIBNAME}_${_header_to_find}_DIRS-NOTFOUND") + find_path(${LIBNAME}_${_header_to_find}_DIRS + NAMES ${_header_to_find} + HINTS ${${LIBNAME}_DIR} + PATH_SUFFIXES include) + else() + set(${LIBNAME}_${_header_to_find}_DIRS "${LIBNAME}_${_header_to_find}_DIRS-NOTFOUND") + find_path(${LIBNAME}_${_header_to_find}_DIRS + NAMES ${_header_to_find} + HINTS ${_inc_env}) + endif() + mark_as_advanced(${LIBNAME}_${_header_to_find}_DIRS) - # Print status if not found - # ------------------------- - if (NOT ${LIBNAME}_${_header_to_find}_DIRS) - Print_Find_Header_Status(${libname} ${_header_to_find}) - endif () + # Print status if not found + # ------------------------- + if (NOT ${LIBNAME}_${_header_to_find}_DIRS) + Print_Find_Header_Status(${libname} ${_header_to_find}) + endif () endfunction(FindHeader) diff --git a/CMakeModules/morse/MorseInit.cmake b/CMakeModules/morse/MorseInit.cmake index c4ed4fd337f4f8ec9e9e7773f34ba2648c84d710..1fd1794f67369ddbb0e04e6b5ff5c6a092b113cc 100644 --- a/CMakeModules/morse/MorseInit.cmake +++ b/CMakeModules/morse/MorseInit.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -31,7 +31,7 @@ include(CheckFunctionExists) # To colorize messages -include(ColorizeMessage) +#include(ColorizeMessage) # To find headers and libs include(FindHeadersAndLibs) @@ -49,9 +49,11 @@ include(Ressources) # Add the path where we handle our FindFOO.cmake to seek for liraries list(APPEND CMAKE_MODULE_PATH ${MORSE_CMAKE_MODULE_PATH}/find) -option(MORSE_VERBOSE_FIND_PACKAGE "Add additional messages concerning no found packages" OFF) -#message("-- ${BoldGreen}MORSE_VERBOSE_FIND_PACKAGE is set to OFF, turn it ON to get" -# "information about packages not found${ColourReset}") +option(MORSE_ENABLE_WARNING "Enable warning messages" OFF) +option(MORSE_ENABLE_COVERAGE "Enable flags for coverage test" OFF) +#option(MORSE_VERBOSE_FIND_PACKAGE "Add additional messages concerning packages not found" OFF) +#message(STATUS "MORSE_VERBOSE_FIND_PACKAGE is set to OFF, turn it ON to get" +# " information about packages not found") ## ## @end file MorseInit.cmake diff --git a/CMakeModules/morse/ParseArguments.cmake b/CMakeModules/morse/ParseArguments.cmake index 1407ded47d3d57d3f7ac8e5048188988e1e9bcb6..23a5ce6ddfb2e2085b1f2b46fc4563307938736c 100644 --- a/CMakeModules/morse/ParseArguments.cmake +++ b/CMakeModules/morse/ParseArguments.cmake @@ -16,7 +16,7 @@ # Univ. of Tennessee, # King Abdullah Univesity of Science and Technology # Univ. of California Berkeley, -# Univ. of Colorado Denver. +# Univ. of Colorado Denver. # # @version 0.9.0 # @author Cedric Castagnede @@ -27,43 +27,43 @@ ### MACRO(PARSE_ARGUMENTS prefix arg_names option_names) - set(DEFAULT_ARGS) - foreach(arg_name ${arg_names}) - set(${prefix}_${arg_name}) - endforeach(arg_name) - foreach(option ${option_names}) - set(${prefix}_${option} FALSE) - endforeach(option) + set(DEFAULT_ARGS) + foreach(arg_name ${arg_names}) + set(${prefix}_${arg_name}) + endforeach(arg_name) + foreach(option ${option_names}) + set(${prefix}_${option} FALSE) + endforeach(option) - set(current_arg_name DEFAULT_ARGS) - set(current_arg_list) - foreach(arg ${ARGN}) - set(larg_names ${arg_names}) - list(FIND larg_names "${arg}" is_arg_name) - if(is_arg_name GREATER -1) - set(${prefix}_${current_arg_name} ${current_arg_list}) - set(current_arg_name ${arg}) - set(current_arg_list) - else(is_arg_name GREATER -1) - set(loption_names ${option_names}) - list(FIND loption_names "${arg}" is_option) - if(is_option GREATER -1) - set(${prefix}_${arg} TRUE) - else(is_option GREATER -1) - set(current_arg_list ${current_arg_list} ${arg}) - endif(is_option GREATER -1) - endif(is_arg_name GREATER -1) - endforeach(arg) - set(${prefix}_${current_arg_name} ${current_arg_list}) + set(current_arg_name DEFAULT_ARGS) + set(current_arg_list) + foreach(arg ${ARGN}) + set(larg_names ${arg_names}) + list(FIND larg_names "${arg}" is_arg_name) + if(is_arg_name GREATER -1) + set(${prefix}_${current_arg_name} ${current_arg_list}) + set(current_arg_name ${arg}) + set(current_arg_list) + else(is_arg_name GREATER -1) + set(loption_names ${option_names}) + list(FIND loption_names "${arg}" is_option) + if(is_option GREATER -1) + set(${prefix}_${arg} TRUE) + else(is_option GREATER -1) + set(current_arg_list ${current_arg_list} ${arg}) + endif(is_option GREATER -1) + endif(is_arg_name GREATER -1) + endforeach(arg) + set(${prefix}_${current_arg_name} ${current_arg_list}) ENDMACRO(PARSE_ARGUMENTS) MACRO(CAR var) - set(${var} ${ARGV1}) + set(${var} ${ARGV1}) ENDMACRO(CAR) MACRO(CDR var junk) - set(${var} ${ARGN}) + set(${var} ${ARGN}) ENDMACRO(CDR) ## diff --git a/CMakeModules/morse/PrintFindStatus.cmake b/CMakeModules/morse/PrintFindStatus.cmake index 1ea56edb0b856fe1bbd482a5aef2c65a195f12d0..54e33a7d7f1718bde020cb05eff833f97cefa035 100644 --- a/CMakeModules/morse/PrintFindStatus.cmake +++ b/CMakeModules/morse/PrintFindStatus.cmake @@ -60,133 +60,133 @@ # This macro informs why the _header_to_find file has not been found macro(Print_Find_Header_Status _libname _header_to_find) - # save _libname upper and lower case - string(TOUPPER ${_libname} LIBNAME) - string(TOLOWER ${_libname} libname) - - # print status - #message(" ") - if(${LIBNAME}_INCDIR) - message("${Blue}${LIBNAME}_INCDIR is defined but ${_header_to_find}" - "has not been found in ${${LIBNAME}_INCDIR}${ColourReset}") + # save _libname upper and lower case + string(TOUPPER ${_libname} LIBNAME) + string(TOLOWER ${_libname} libname) + + # print status + #message(" ") + if(${LIBNAME}_INCDIR) + message("${Blue}${LIBNAME}_INCDIR is defined but ${_header_to_find}" + "has not been found in ${${LIBNAME}_INCDIR}${ColourReset}") + else() + if(${LIBNAME}_DIR) + message("${Blue}${LIBNAME}_DIR is defined but" + "${_header_to_find} has not been found in" + "${${LIBNAME}_DIR}/include${ColourReset}") else() - if(${LIBNAME}_DIR) - message("${Blue}${LIBNAME}_DIR is defined but" - "${_header_to_find} has not been found in" - "${${LIBNAME}_DIR}/include${ColourReset}") - else() - message("${Blue}${_header_to_find} not found." - "Nor ${LIBNAME}_DIR neither ${LIBNAME}_INCDIR" - "are defined so that we looked for ${_header_to_find} in" - "system paths (INCLUDE, CPATH, C_INCLUDE_PATH," - "INCLUDE_PATH, CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES" - ", CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)${ColourReset}") - if(_inc_env) - message("${Blue}${_header_to_find} has not been found in" - "${_inc_env}${ColourReset}") - endif() - endif() + message("${Blue}${_header_to_find} not found." + "Nor ${LIBNAME}_DIR neither ${LIBNAME}_INCDIR" + "are defined so that we looked for ${_header_to_find} in" + "system paths (INCLUDE, CPATH, C_INCLUDE_PATH," + "INCLUDE_PATH, CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES" + ", CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)${ColourReset}") + if(_inc_env) + message("${Blue}${_header_to_find} has not been found in" + "${_inc_env}${ColourReset}") + endif() endif() - message("${BoldBlue}Please indicate where to find ${_header_to_find}. You have three options:\n" - "- Option 1: Provide the root directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" - "- Option 2: Provide the directory where to find the headers with cmake option: -D${LIBNAME}_INCDIR=your/path/to/${libname}/include/\n" - "- Option 3: Update your environment variable (INCLUDE or CPATH)\n" - "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") - #message(" ") + endif() + message("${BoldBlue}Please indicate where to find ${_header_to_find}. You have three options:\n" + "- Option 1: Provide the root directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" + "- Option 2: Provide the directory where to find the headers with cmake option: -D${LIBNAME}_INCDIR=your/path/to/${libname}/include/\n" + "- Option 3: Update your environment variable (INCLUDE or CPATH)\n" + "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") + #message(" ") endmacro() # This macro informs why the _lib_to_find file has not been found macro(Print_Find_Library_Status _libname _lib_to_find) - # save _libname upper/lower case - string(TOUPPER ${_libname} LIBNAME) - string(TOLOWER ${_libname} libname) - - # print status - #message(" ") - if(${LIBNAME}_LIBDIR) - message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" - "has not been found in ${${LIBNAME}_LIBDIR}${ColourReset}") + # save _libname upper/lower case + string(TOUPPER ${_libname} LIBNAME) + string(TOLOWER ${_libname} libname) + + # print status + #message(" ") + if(${LIBNAME}_LIBDIR) + message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" + "has not been found in ${${LIBNAME}_LIBDIR}${ColourReset}") + else() + if(${LIBNAME}_DIR) + message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" + "has not been found in ${${LIBNAME}_DIR}/lib(or /lib32 or" + "/lib64)${ColourReset}") else() - if(${LIBNAME}_DIR) - message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" - "has not been found in ${${LIBNAME}_DIR}/lib(or /lib32 or" - "/lib64)${ColourReset}") - else() - message("${Yellow}${_lib_to_find} not found." - "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" - "are defined so that we looked for ${_lib_to_find} in" - "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," - "Mac: DYLD_LIBRARY_PATH," - "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," - "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") - if(_lib_env) - message("${Yellow}${_lib_to_find} has not been found in" - "${_lib_env}${ColourReset}") - endif() - endif() + message("${Yellow}${_lib_to_find} not found." + "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" + "are defined so that we looked for ${_lib_to_find} in" + "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," + "Mac: DYLD_LIBRARY_PATH," + "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," + "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") + if(_lib_env) + message("${Yellow}${_lib_to_find} has not been found in" + "${_lib_env}${ColourReset}") + endif() endif() - message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" - "- Option 1: Provide the root directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" - "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") + endif() + message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" + "- Option 1: Provide the root directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" + "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") endmacro() # This macro informs why the _lib_to_find file has not been found macro(Print_Find_Library_Blas_Status _libname _lib_to_find) - # save _libname upper/lower case - string(TOUPPER ${_libname} LIBNAME) - string(TOLOWER ${_libname} libname) - - # print status - #message(" ") - if(${LIBNAME}_LIBDIR) - message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" - "has not been found in ${ARGN}${ColourReset}") + # save _libname upper/lower case + string(TOUPPER ${_libname} LIBNAME) + string(TOLOWER ${_libname} libname) + + # print status + #message(" ") + if(${LIBNAME}_LIBDIR) + message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" + "has not been found in ${ARGN}${ColourReset}") + else() + if(${LIBNAME}_DIR) + message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" + "has not been found in ${ARGN}${ColourReset}") else() - if(${LIBNAME}_DIR) - message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" - "has not been found in ${ARGN}${ColourReset}") - else() - message("${Yellow}${_lib_to_find} not found." - "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" - "are defined so that we look for ${_lib_to_find} in" - "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," - "Mac: DYLD_LIBRARY_PATH," - "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," - "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") - if(_lib_env) - message("${Yellow}${_lib_to_find} has not been found in" - "${_lib_env}${ColourReset}") - endif() - endif() + message("${Yellow}${_lib_to_find} not found." + "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" + "are defined so that we look for ${_lib_to_find} in" + "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," + "Mac: DYLD_LIBRARY_PATH," + "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," + "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") + if(_lib_env) + message("${Yellow}${_lib_to_find} has not been found in" + "${_lib_env}${ColourReset}") + endif() endif() - message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" - "- Option 1: Provide the root directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" - "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") + endif() + message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" + "- Option 1: Provide the root directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" + "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") endmacro() # This macro informs why the _lib_to_find file has not been found macro(Print_Find_Library_Blas_CheckFunc_Status _name) - # save _libname upper/lower case - string(TOUPPER ${_name} FUNCNAME) - string(TOLOWER ${_name} funcname) + # save _libname upper/lower case + string(TOUPPER ${_name} FUNCNAME) + string(TOLOWER ${_name} funcname) - # print status - #message(" ") - message("${Red}Libs have been found but check of symbol ${_name} failed " - "with following libraries ${ARGN}${ColourReset}") - message("${BoldRed}Please open your error file CMakeFiles/CMakeError.log" - "to figure out why it fails${ColourReset}") - #message(" ") + # print status + #message(" ") + message("${Red}Libs have been found but check of symbol ${_name} failed " + "with following libraries ${ARGN}${ColourReset}") + message("${BoldRed}Please open your error file CMakeFiles/CMakeError.log" + "to figure out why it fails${ColourReset}") + #message(" ") endmacro() @@ -195,16 +195,16 @@ endmacro() # ex: Print_Find_Pkgconfig_Status(foo foo.pc ${PATHLIST} macro(Print_Find_Pkgconfig_Status _libname _pc_to_find) - # save _libname lower case - string(TOLOWER ${_libname} libname) - - # print status - #message(" ") - message("${Magenta}${_pc_to_find} has not been found in" - "${ARGN}${ColourReset}") - message("${BoldMagenta}If you really want to use the pkg-config file of" - "${libname}, please update your PKG_CONFIG_PATH with the path" - "where ${_pc_to_find} states${ColourReset}") - #message(" ") + # save _libname lower case + string(TOLOWER ${_libname} libname) + + # print status + #message(" ") + message("${Magenta}${_pc_to_find} has not been found in" + "${ARGN}${ColourReset}") + message("${BoldMagenta}If you really want to use the pkg-config file of" + "${libname}, please update your PKG_CONFIG_PATH with the path" + "where ${_pc_to_find} states${ColourReset}") + #message(" ") endmacro() diff --git a/CMakeModules/morse/Ressources.cmake b/CMakeModules/morse/Ressources.cmake index 15b7a35d11cd2cd2ddb5ff358bb3139bbe92cfa0..cd5e2a1eeb4af93710b53745505d3ffa1dac69e2 100644 --- a/CMakeModules/morse/Ressources.cmake +++ b/CMakeModules/morse/Ressources.cmake @@ -29,28 +29,28 @@ if(NOT DEFINED PROCESSOR_COUNT) - # Unknown: - set(NUMBER_OF_CPU 0) + # Unknown: + set(NUMBER_OF_CPU 0) - # Linux: - set(cpuinfo_file "/proc/cpuinfo") - if(EXISTS "${cpuinfo_file}") - file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") - list(LENGTH procs NUMBER_OF_CPU) - endif() + # Linux: + set(cpuinfo_file "/proc/cpuinfo") + if(EXISTS "${cpuinfo_file}") + file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") + list(LENGTH procs NUMBER_OF_CPU) + endif() - # Mac: - if(APPLE) - find_program(cmd_sys_pro "system_profiler") - if(cmd_sys_pro) - execute_process(COMMAND ${cmd_sys_pro} SPHardwareDataType OUTPUT_VARIABLE info) - string(REGEX REPLACE "^.*Total Number of Cores: ([0-9]+).*$" "\\1" - NUMBER_OF_CPU "${info}") - endif() + # Mac: + if(APPLE) + find_program(cmd_sys_pro "system_profiler") + if(cmd_sys_pro) + execute_process(COMMAND ${cmd_sys_pro} SPHardwareDataType OUTPUT_VARIABLE info) + string(REGEX REPLACE "^.*Total Number of Cores: ([0-9]+).*$" "\\1" + NUMBER_OF_CPU "${info}") endif() + endif() - # Windows: - if(WIN32) + # Windows: + if(WIN32) set(NUMBER_OF_CPU "$ENV{NUMBER_OF_PROCESSORS}") - endif() + endif() endif() diff --git a/CMakeModules/morse/RulesPrecisions.cmake b/CMakeModules/morse/RulesPrecisions.cmake index bef0c4418aa0aba574c03309df6dd921f7446998..7e100c35f4da37069c0deb6de3094b3fdbda377a 100644 --- a/CMakeModules/morse/RulesPrecisions.cmake +++ b/CMakeModules/morse/RulesPrecisions.cmake @@ -70,25 +70,25 @@ set( _prec_C OFF ) set( _prec_Z OFF ) set( _prec_ZC OFF ) foreach(_prec ${RP_${CMAKE_PROJECT_NAME}_PRECISIONS}) - if ( ${_prec} STREQUAL "zc" ) + if ( ${_prec} STREQUAL zc ) set( _prec_S ON ) set( _prec_D ON ) set( _prec_C ON ) set( _prec_Z ON ) set( _prec_ZC ON ) - elseif( ${_prec} STREQUAL "z" ) + elseif( ${_prec} STREQUAL z ) set( _prec_D ON ) set( _prec_Z ON ) - elseif( ${_prec} STREQUAL "c" ) + elseif( ${_prec} STREQUAL c ) set( _prec_S ON ) set( _prec_C ON ) - elseif( ${_prec} STREQUAL "ds" ) + elseif( ${_prec} STREQUAL ds ) set( _prec_S ON ) set( _prec_D ON ) set( _prec_DS ON ) - elseif( ${_prec} STREQUAL "d" ) + elseif( ${_prec} STREQUAL d ) set( _prec_S ON ) - elseif( ${_prec} STREQUAL "s" ) + elseif( ${_prec} STREQUAL s ) set( _prec_S ON ) endif() endforeach() @@ -223,27 +223,27 @@ MACRO(precisions_rules_py) # Force the copy of the original files in the binary_dir # for VPATH compilation if( NOT ${CMAKE_PROJECT_NAME}_COMPILE_INPLACE ) - set(generate_out 1) + set(generate_out 1) else( NOT ${CMAKE_PROJECT_NAME}_COMPILE_INPLACE ) - string(COMPARE NOTEQUAL "${_dependency_OUTPUT}" "${_dependency_INPUT}" generate_out ) + string(COMPARE NOTEQUAL "${_dependency_OUTPUT}" "${_dependency_INPUT}" generate_out ) endif() # We generate a dependency only if a file will be generated if( got_file ) - if( generate_out ) - # the custom command is executed in CMAKE_CURRENT_BINARY_DIR - ADD_CUSTOM_COMMAND( - OUTPUT ${_dependency_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E remove -f ${_dependency_OUTPUT} && ${pythoncmd} && chmod a-w ${_dependency_OUTPUT} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_dependency_INPUT} ${RP_CODEGEN} ${RP_${CMAKE_PROJECT_NAME}_DICTIONNARY}) + if( generate_out ) + # the custom command is executed in CMAKE_CURRENT_BINARY_DIR + ADD_CUSTOM_COMMAND( + OUTPUT ${_dependency_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E remove -f ${_dependency_OUTPUT} && ${pythoncmd} && chmod a-w ${_dependency_OUTPUT} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_dependency_INPUT} ${RP_CODEGEN} ${RP_${CMAKE_PROJECT_NAME}_DICTIONNARY}) - set_SOURCE_FILES_PROPERTIES(${_dependency_OUTPUT} PROPERTIES COMPILE_FLAGS "-DPRECISION_${_dependency_PREC}" GENERATED 1 IS_IN_BINARY_DIR 1 ) + set_SOURCE_FILES_PROPERTIES(${_dependency_OUTPUT} PROPERTIES COMPILE_FLAGS "-DPRECISION_${_dependency_PREC}" GENERATED 1 IS_IN_BINARY_DIR 1 ) - else( generate_out ) - set_SOURCE_FILES_PROPERTIES(${_dependency_OUTPUT} PROPERTIES COMPILE_FLAGS "-DPRECISION_${_dependency_PREC}" GENERATED 0 ) - endif( generate_out ) + else( generate_out ) + set_SOURCE_FILES_PROPERTIES(${_dependency_OUTPUT} PROPERTIES COMPILE_FLAGS "-DPRECISION_${_dependency_PREC}" GENERATED 0 ) + endif( generate_out ) - list(APPEND ${OUTPUTLIST} ${_dependency_OUTPUT}) + list(APPEND ${OUTPUTLIST} ${_dependency_OUTPUT}) endif( got_file ) endif() endforeach() diff --git a/CMakeModules/morse/find/FindBLAS.cmake b/CMakeModules/morse/find/FindBLAS.cmake index cbf7769442aeb7f72f5cf59b83e106a0ba0fb177..43132541ddcc0653822926aae4932ac84508a80a 100644 --- a/CMakeModules/morse/find/FindBLAS.cmake +++ b/CMakeModules/morse/find/FindBLAS.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -40,11 +40,12 @@ # are not given as cmake variable: BLAS_DIR, BLAS_INCDIR, BLAS_LIBDIR # For MKL case and if no paths are given as hints, we will try to use the MKLROOT # environment variable +# BLAS_VERBOSE Print some additional information during BLAS libraries detection ########## ### List of vendors (BLA_VENDOR) valid in this module ########## List of vendors (BLA_VENDOR) valid in this module ## Open (for OpenBlas), Eigen (for EigenBlas), Goto, ATLAS PhiPACK, -##  CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, +##  CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT ## Intel10_32 (intel mkl v10 32 bit), Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model), ## Intel10_64lp_seq (intel mkl v10 64 bit,sequential code, lp64 model), ## Intel( older versions of mkl 32 and 64 bit), @@ -77,92 +78,71 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) - -# Set some colors -#if(NOT WIN32) -# string(ASCII 27 Esc) -# set(ColourReset "${Esc}[m") -# set(ColourBold "${Esc}[1m") -# set(Red "${Esc}[31m") -# set(Green "${Esc}[32m") -# set(Yellow "${Esc}[33m") -# set(Blue "${Esc}[34m") -# set(Magenta "${Esc}[35m") -# set(Cyan "${Esc}[36m") -# set(White "${Esc}[37m") -# set(BoldRed "${Esc}[1;31m") -# set(BoldGreen "${Esc}[1;32m") -# set(BoldYellow "${Esc}[1;33m") -# set(BoldBlue "${Esc}[1;34m") -# set(BoldMagenta "${Esc}[1;35m") -# set(BoldCyan "${Esc}[1;36m") -# set(BoldWhite "${Esc}[1;37m") -#endif() - ## Some macros to print status when search for headers and libs # This macro informs why the _lib_to_find file has not been found macro(Print_Find_Library_Blas_Status _libname _lib_to_find) - # save _libname upper/lower case - string(TOUPPER ${_libname} LIBNAME) - string(TOLOWER ${_libname} libname) - - # print status - #message(" ") - if(${LIBNAME}_LIBDIR) - message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" - "has not been found in ${ARGN}${ColourReset}") + # save _libname upper/lower case + string(TOUPPER ${_libname} LIBNAME) + string(TOLOWER ${_libname} libname) + + # print status + #message(" ") + if(${LIBNAME}_LIBDIR) + message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" + "has not been found in ${ARGN}${ColourReset}") + else() + if(${LIBNAME}_DIR) + message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" + "has not been found in ${ARGN}${ColourReset}") else() - if(${LIBNAME}_DIR) - message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" - "has not been found in ${ARGN}${ColourReset}") - else() - message("${Yellow}${_lib_to_find} not found." - "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" - "are defined so that we look for ${_lib_to_find} in" - "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," - "Mac: DYLD_LIBRARY_PATH," - "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," - "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") - if(_lib_env) - message("${Yellow}${_lib_to_find} has not been found in" - "${_lib_env}${ColourReset}") - endif() - endif() + message("${Yellow}${_lib_to_find} not found." + "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" + "are defined so that we look for ${_lib_to_find} in" + "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," + "Mac: DYLD_LIBRARY_PATH," + "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," + "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") + if(_lib_env) + message("${Yellow}${_lib_to_find} has not been found in" + "${_lib_env}${ColourReset}") + endif() endif() - message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" - "- Option 1: Provide the Installation directory of BLAS library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" - "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") + endif() + message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" + "- Option 1: Provide the Installation directory of BLAS library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" + "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") endmacro() # This macro informs why the _lib_to_find file has not been found macro(Print_Find_Library_Blas_CheckFunc_Status _name) - # save _libname upper/lower case - string(TOUPPER ${_name} FUNCNAME) - string(TOLOWER ${_name} funcname) + # save _libname upper/lower case + string(TOUPPER ${_name} FUNCNAME) + string(TOLOWER ${_name} funcname) - # print status - #message(" ") - message("${Red}Libs have been found but check of symbol ${_name} failed " - "with following libraries ${ARGN}${ColourReset}") - message("${BoldRed}Please open your error file CMakeFiles/CMakeError.log" - "to figure out why it fails${ColourReset}") - #message(" ") + # print status + #message(" ") + message("${Red}Libs have been found but check of symbol ${_name} failed " + "with following libraries ${ARGN}${ColourReset}") + message("${BoldRed}Please open your error file CMakeFiles/CMakeError.log" + "to figure out why it fails${ColourReset}") + #message(" ") endmacro() if (NOT BLAS_FOUND) - set(BLAS_DIR "" CACHE PATH "Installation directory of BLAS library") - if (NOT BLAS_FIND_QUIETLY) - message(STATUS "A cache variable, namely BLAS_DIR, has been set to specify the install directory of BLAS") - endif() + set(BLAS_DIR "" CACHE PATH "Installation directory of BLAS library") + if (NOT BLAS_FIND_QUIETLY) + message(STATUS "A cache variable, namely BLAS_DIR, has been set to specify the install directory of BLAS") + endif() endif() option(BLAS_VERBOSE "Print some additional information during BLAS libraries detection" OFF) +mark_as_advanced(BLAS_VERBOSE) include(CheckFunctionExists) include(CheckFortranFunctionExists) @@ -172,163 +152,166 @@ set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) # Check the language being used get_property( _LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES ) if( _LANGUAGES_ MATCHES Fortran ) - set( _CHECK_FORTRAN TRUE ) + set( _CHECK_FORTRAN TRUE ) elseif( (_LANGUAGES_ MATCHES C) OR (_LANGUAGES_ MATCHES CXX) ) - set( _CHECK_FORTRAN FALSE ) + set( _CHECK_FORTRAN FALSE ) else() - if(BLAS_FIND_REQUIRED) - message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.") - else() - message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)") - return() - endif() + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.") + else() + message(STATUS "Looking for BLAS... - NOT found (Unsupported languages)") + return() + endif() endif() macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread) -# This macro checks for the existence of the combination of fortran libraries -# given by _list. If the combination is found, this macro checks (using the -# Check_Fortran_Function_Exists macro) whether can link against that library -# combination using the name of a routine given by _name using the linker -# flags given by _flags. If the combination of libraries is found and passes -# the link test, LIBRARIES is set to the list of complete library paths that -# have been found. Otherwise, LIBRARIES is set to FALSE. - -# N.B. _prefix is the prefix applied to the names of all cached variables that -# are generated internally and marked advanced by this macro. - - set(_libdir ${ARGN}) - - set(_libraries_work TRUE) - set(${LIBRARIES}) - set(_combined_name) - set(ENV_MKLROOT "$ENV{MKLROOT}") - set(ENV_BLAS_DIR "$ENV{BLAS_DIR}") - set(ENV_BLAS_LIBDIR "$ENV{BLAS_LIBDIR}") - if (NOT _libdir) - if (BLAS_LIBDIR) - list(APPEND _libdir "${BLAS_LIBDIR}") - elseif (BLAS_DIR) - list(APPEND _libdir "${BLAS_DIR}") - list(APPEND _libdir "${BLAS_DIR}/lib") - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${BLAS_DIR}/lib64") - list(APPEND _libdir "${BLAS_DIR}/lib/intel64") - else() - list(APPEND _libdir "${BLAS_DIR}/lib32") - list(APPEND _libdir "${BLAS_DIR}/lib/ia32") - endif() - elseif(ENV_BLAS_LIBDIR) - list(APPEND _libdir "${ENV_BLAS_LIBDIR}") - elseif(ENV_BLAS_DIR) - list(APPEND _libdir "${ENV_BLAS_DIR}") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib") - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib64") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib/intel64") - else() - list(APPEND _libdir "${ENV_BLAS_DIR}/lib32") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib/ia32") - endif() - else() - if (ENV_MKLROOT) - list(APPEND _libdir "${ENV_MKLROOT}/lib") - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${ENV_MKLROOT}/lib64") - list(APPEND _libdir "${ENV_MKLROOT}/lib/intel64") - else() - list(APPEND _libdir "${ENV_MKLROOT}/lib32") - list(APPEND _libdir "${ENV_MKLROOT}/lib/ia32") - endif() - endif() - if (WIN32) - string(REPLACE ":" ";" _libdir2 "$ENV{LIB}") - elseif (APPLE) - string(REPLACE ":" ";" _libdir2 "$ENV{DYLD_LIBRARY_PATH}") - else () - string(REPLACE ":" ";" _libdir2 "$ENV{LD_LIBRARY_PATH}") - endif () - list(APPEND _libdir "${_libdir2}") - list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() - endif () - - if (BLAS_VERBOSE) - message("${Cyan}Try to find BLAS libraries: ${_list}") - endif () + # This macro checks for the existence of the combination of fortran libraries + # given by _list. If the combination is found, this macro checks (using the + # Check_Fortran_Function_Exists macro) whether can link against that library + # combination using the name of a routine given by _name using the linker + # flags given by _flags. If the combination of libraries is found and passes + # the link test, LIBRARIES is set to the list of complete library paths that + # have been found. Otherwise, LIBRARIES is set to FALSE. + + # N.B. _prefix is the prefix applied to the names of all cached variables that + # are generated internally and marked advanced by this macro. + + set(_libdir ${ARGN}) + + set(_libraries_work TRUE) + set(${LIBRARIES}) + set(_combined_name) + set(ENV_MKLROOT "$ENV{MKLROOT}") + set(ENV_BLAS_DIR "$ENV{BLAS_DIR}") + set(ENV_BLAS_LIBDIR "$ENV{BLAS_LIBDIR}") + if (NOT _libdir) + if (BLAS_LIBDIR) + list(APPEND _libdir "${BLAS_LIBDIR}") + elseif (BLAS_DIR) + list(APPEND _libdir "${BLAS_DIR}") + list(APPEND _libdir "${BLAS_DIR}/lib") + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + list(APPEND _libdir "${BLAS_DIR}/lib64") + list(APPEND _libdir "${BLAS_DIR}/lib/intel64") + else() + list(APPEND _libdir "${BLAS_DIR}/lib32") + list(APPEND _libdir "${BLAS_DIR}/lib/ia32") + endif() + elseif(ENV_BLAS_LIBDIR) + list(APPEND _libdir "${ENV_BLAS_LIBDIR}") + elseif(ENV_BLAS_DIR) + list(APPEND _libdir "${ENV_BLAS_DIR}") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib") + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib64") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib/intel64") + else() + list(APPEND _libdir "${ENV_BLAS_DIR}/lib32") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib/ia32") + endif() + else() + if (ENV_MKLROOT) + list(APPEND _libdir "${ENV_MKLROOT}/lib") + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + list(APPEND _libdir "${ENV_MKLROOT}/lib64") + list(APPEND _libdir "${ENV_MKLROOT}/lib/intel64") + else() + list(APPEND _libdir "${ENV_MKLROOT}/lib32") + list(APPEND _libdir "${ENV_MKLROOT}/lib/ia32") + endif() + endif() + if (WIN32) + string(REPLACE ":" ";" _libdir2 "$ENV{LIB}") + elseif (APPLE) + string(REPLACE ":" ";" _libdir2 "$ENV{DYLD_LIBRARY_PATH}") + else () + string(REPLACE ":" ";" _libdir2 "$ENV{LD_LIBRARY_PATH}") + endif () + list(APPEND _libdir "${_libdir2}") + list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() + endif () - foreach(_library ${_list}) - set(_combined_name ${_combined_name}_${_library}) - - if(_libraries_work) - if (BLA_STATIC) - if (WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif () - if (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else () - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif () - else () - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif () - endif () - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - HINTS ${_libdir} - ) - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - # Print status if not found - # ------------------------- - if (NOT ${_prefix}_${_library}_LIBRARY AND NOT BLAS_FIND_QUIETLY AND BLAS_VERBOSE) - Print_Find_Library_Blas_Status(blas ${_library} ${_libdir}) - endif () - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) - endif(_libraries_work) - endforeach(_library ${_list}) + if (BLAS_VERBOSE) + message("${Cyan}Try to find BLAS libraries: ${_list}") + endif () - if(_libraries_work) - # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES "${_flags};${${LIBRARIES}};${_thread}") - set(CMAKE_REQUIRED_FLAGS "${BLAS_COMPILER_FLAGS}") - if (BLAS_VERBOSE) - message("${Cyan}BLAS libs found for BLA_VENDOR ${BLA_VENDOR}." - "Try to compile symbol ${_name} with following libraries:" - "${CMAKE_REQUIRED_LIBRARIES}") - endif () - if(NOT BLAS_FOUND) - unset(${_prefix}${_combined_name}_WORKS CACHE) - endif() - if (_CHECK_FORTRAN) - if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - string(REPLACE "mkl_intel_lp64" "mkl_gf_lp64" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - string(REPLACE "mkl_intel_ilp64" "mkl_gf_ilp64" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - endif() - check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) - else() - check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) - endif() - mark_as_advanced(${_prefix}${_combined_name}_WORKS) - set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) - # Print status if not found - # ------------------------- - if (NOT _libraries_work AND NOT BLAS_FIND_QUIETLY AND BLAS_VERBOSE) - Print_Find_Library_Blas_CheckFunc_Status(${_name} ${CMAKE_REQUIRED_LIBRARIES}) - endif () - set(CMAKE_REQUIRED_LIBRARIES) - endif() + foreach(_library ${_list}) + set(_combined_name ${_combined_name}_${_library}) if(_libraries_work) - set(${LIBRARIES} ${${LIBRARIES}} ${_thread}) - else(_libraries_work) - set(${LIBRARIES} FALSE) + if (BLA_STATIC) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif () + if (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else () + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif () + else () + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif () + endif () + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + HINTS ${_libdir} + NO_DEFAULT_PATH + ) + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + # Print status if not found + # ------------------------- + if (NOT ${_prefix}_${_library}_LIBRARY AND NOT BLAS_FIND_QUIETLY AND BLAS_VERBOSE) + Print_Find_Library_Blas_Status(blas ${_library} ${_libdir}) + endif () + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) endif(_libraries_work) + endforeach(_library ${_list}) + + if(_libraries_work) + # Test this combination of libraries. + if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND BLA_STATIC) + list(INSERT ${LIBRARIES} 0 "-Wl,--start-group") + list(APPEND ${LIBRARIES} "-Wl,--end-group") + endif() + set(CMAKE_REQUIRED_LIBRARIES "${_flags};${${LIBRARIES}};${_thread}") + set(CMAKE_REQUIRED_FLAGS "${BLAS_COMPILER_FLAGS}") + if (BLAS_VERBOSE) + message("${Cyan}BLAS libs found for BLA_VENDOR ${BLA_VENDOR}." + "Try to compile symbol ${_name} with following libraries:" + "${CMAKE_REQUIRED_LIBRARIES}") + endif () + if(NOT BLAS_FOUND) + unset(${_prefix}${_combined_name}_WORKS CACHE) + endif() + if (_CHECK_FORTRAN) + if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + string(REPLACE "mkl_intel_lp64" "mkl_gf_lp64" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + string(REPLACE "mkl_intel_ilp64" "mkl_gf_ilp64" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + endif() + check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) + else() + check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) + endif() + mark_as_advanced(${_prefix}${_combined_name}_WORKS) + set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) + # Print status if not found + # ------------------------- + if (NOT _libraries_work AND NOT BLAS_FIND_QUIETLY AND BLAS_VERBOSE) + Print_Find_Library_Blas_CheckFunc_Status(${_name} ${CMAKE_REQUIRED_LIBRARIES}) + endif () + set(CMAKE_REQUIRED_LIBRARIES) + endif() -# message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") + if(_libraries_work) + set(${LIBRARIES} ${${LIBRARIES}} ${_thread}) + else(_libraries_work) + set(${LIBRARIES} FALSE) + endif(_libraries_work) endmacro(Check_Fortran_Libraries) @@ -337,16 +320,17 @@ set(BLAS_LINKER_FLAGS) set(BLAS_LIBRARIES) set(BLAS95_LIBRARIES) if ($ENV{BLA_VENDOR} MATCHES ".+") - set(BLA_VENDOR $ENV{BLA_VENDOR}) + set(BLA_VENDOR $ENV{BLA_VENDOR}) else () - if(NOT BLA_VENDOR) - set(BLA_VENDOR "All") - endif() + if(NOT BLA_VENDOR) + set(BLA_VENDOR "All") + endif() endif () #BLAS in intel mkl 10 library? (em64t 64bit) if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") + if(NOT BLAS_LIBRARIES OR BLA_VENDOR MATCHES "Intel*") # Looking for include # ------------------- @@ -357,28 +341,28 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") set(ENV_BLAS_DIR "$ENV{BLAS_DIR}") set(ENV_BLAS_INCDIR "$ENV{BLAS_INCDIR}") if(ENV_BLAS_INCDIR) - list(APPEND _inc_env "${ENV_BLAS_INCDIR}") + list(APPEND _inc_env "${ENV_BLAS_INCDIR}") elseif(ENV_BLAS_DIR) - list(APPEND _inc_env "${ENV_BLAS_DIR}") - list(APPEND _inc_env "${ENV_BLAS_DIR}/include") + list(APPEND _inc_env "${ENV_BLAS_DIR}") + list(APPEND _inc_env "${ENV_BLAS_DIR}/include") else() - if (ENV_MKLROOT) - list(APPEND _inc_env "${ENV_MKLROOT}/include") - endif() - # system variables - if(WIN32) - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + if (ENV_MKLROOT) + list(APPEND _inc_env "${ENV_MKLROOT}/include") + endif() + # system variables + if(WIN32) + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() endif() list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") @@ -391,43 +375,43 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") # ------------------------------------------------- # call cmake macro to find the header path if(BLAS_INCDIR) - set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND") - find_path(BLAS_mkl.h_DIRS - NAMES mkl.h - HINTS ${BLAS_INCDIR}) + set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND") + find_path(BLAS_mkl.h_DIRS + NAMES mkl.h + HINTS ${BLAS_INCDIR}) else() - if(BLAS_DIR) - set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND") - find_path(BLAS_mkl.h_DIRS - NAMES mkl.h - HINTS ${BLAS_DIR} - PATH_SUFFIXES "include") - else() - set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND") - find_path(BLAS_mkl.h_DIRS - NAMES mkl.h - HINTS ${PATH_TO_LOOK_FOR}) - endif() + if(BLAS_DIR) + set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND") + find_path(BLAS_mkl.h_DIRS + NAMES mkl.h + HINTS ${BLAS_DIR} + PATH_SUFFIXES "include") + else() + set(BLAS_mkl.h_DIRS "BLAS_mkl.h_DIRS-NOTFOUND") + find_path(BLAS_mkl.h_DIRS + NAMES mkl.h + HINTS ${PATH_TO_LOOK_FOR}) + endif() endif() mark_as_advanced(BLAS_mkl.h_DIRS) # If found, add path to cmake variable # ------------------------------------ if (BLAS_mkl.h_DIRS) - set(BLAS_INCLUDE_DIRS "${BLAS_mkl.h_DIRS}") + set(BLAS_INCLUDE_DIRS "${BLAS_mkl.h_DIRS}") else () - set(BLAS_INCLUDE_DIRS "BLAS_INCLUDE_DIRS-NOTFOUND") - if(NOT BLAS_FIND_QUIETLY) - message(STATUS "Looking for BLAS -- mkl.h not found") - endif() + set(BLAS_INCLUDE_DIRS "BLAS_INCLUDE_DIRS-NOTFOUND") + if(NOT BLAS_FIND_QUIETLY) + message(STATUS "Looking for BLAS -- mkl.h not found") + endif() endif() if (WIN32) - string(REPLACE ":" ";" _libdir "$ENV{LIB}") + string(REPLACE ":" ";" _libdir "$ENV{LIB}") elseif (APPLE) - string(REPLACE ":" ";" _libdir "$ENV{DYLD_LIBRARY_PATH}") + string(REPLACE ":" ";" _libdir "$ENV{DYLD_LIBRARY_PATH}") else () - string(REPLACE ":" ";" _libdir "$ENV{LD_LIBRARY_PATH}") + string(REPLACE ":" ";" _libdir "$ENV{LD_LIBRARY_PATH}") endif () list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") @@ -435,8 +419,8 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") # -------- set(OMP_iomp5_LIBRARY "OMP_iomp5_LIBRARY-NOTFOUND") find_library(OMP_iomp5_LIBRARY - NAMES iomp5 - HINTS ${_libdir} + NAMES iomp5 + HINTS ${_libdir} ) mark_as_advanced(OMP_iomp5_LIBRARY) set(OMP_LIB "") @@ -444,280 +428,300 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") # ------- set(OMP_gomp_LIBRARY "OMP_gomp_LIBRARY-NOTFOUND") find_library(OMP_gomp_LIBRARY - NAMES gomp - HINTS ${_libdir} + NAMES gomp + HINTS ${_libdir} ) mark_as_advanced(OMP_gomp_LIBRARY) # choose one or another depending on the compilo if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - if (OMP_gomp_LIBRARY) - set(OMP_LIB "${OMP_gomp_LIBRARY}") - endif() + if (OMP_gomp_LIBRARY) + set(OMP_LIB "${OMP_gomp_LIBRARY}") + endif() else(CMAKE_C_COMPILER_ID STREQUAL "Intel") - if (OMP_iomp5_LIBRARY) - set(OMP_LIB "${OMP_iomp5_LIBRARY}") - endif() + if (OMP_iomp5_LIBRARY) + set(OMP_LIB "${OMP_iomp5_LIBRARY}") + endif() endif() if (UNIX AND NOT WIN32) - # m - find_library(M_LIBRARY - NAMES m - HINTS ${_libdir}) - if(M_LIBRARY) - set(LM "-lm") - else() - set(LM "") - endif() - # Fortran - set(LGFORTRAN "") - if (CMAKE_C_COMPILER_ID MATCHES "GNU") - find_library( - FORTRAN_gfortran_LIBRARY - NAMES gfortran - HINTS ${_libdir} - ) - mark_as_advanced(FORTRAN_gfortran_LIBRARY) - if (FORTRAN_gfortran_LIBRARY) - set(LGFORTRAN "${FORTRAN_gfortran_LIBRARY}") - endif() - elseif (CMAKE_C_COMPILER_ID MATCHES "Intel") - find_library( - FORTRAN_ifcore_LIBRARY - NAMES ifcore - HINTS ${_libdir} - ) - mark_as_advanced(FORTRAN_ifcore_LIBRARY) - if (FORTRAN_ifcore_LIBRARY) - set(LGFORTRAN "{FORTRAN_ifcore_LIBRARY}") - endif() - endif() - set(BLAS_COMPILER_FLAGS "") - if (NOT BLA_VENDOR STREQUAL "Intel10_64lp_seq") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") - list(APPEND BLAS_COMPILER_FLAGS "-openmp") - endif() - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - list(APPEND BLAS_COMPILER_FLAGS "-fopenmp") - endif() - endif() - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - if (BLA_VENDOR STREQUAL "Intel10_32") - #list(APPEND BLAS_COMPILER_FLAGS "-m32") - else() - #list(APPEND BLAS_COMPILER_FLAGS "-m64") - endif() - if (NOT BLA_VENDOR STREQUAL "Intel10_64lp_seq") - list(APPEND OMP_LIB "-ldl") - endif() - endif() - - set(additional_flags "") - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(additional_flags "-Wl,--no-as-needed") - endif() + # m + find_library(M_LIBRARY + NAMES m + HINTS ${_libdir}) + mark_as_advanced(M_LIBRARY) + if(M_LIBRARY) + set(LM "-lm") + else() + set(LM "") + endif() + # Fortran + set(LGFORTRAN "") + if (CMAKE_C_COMPILER_ID MATCHES "GNU") + find_library( + FORTRAN_gfortran_LIBRARY + NAMES gfortran + HINTS ${_libdir} + ) + mark_as_advanced(FORTRAN_gfortran_LIBRARY) + if (FORTRAN_gfortran_LIBRARY) + set(LGFORTRAN "${FORTRAN_gfortran_LIBRARY}") + endif() + elseif (CMAKE_C_COMPILER_ID MATCHES "Intel") + find_library( + FORTRAN_ifcore_LIBRARY + NAMES ifcore + HINTS ${_libdir} + ) + mark_as_advanced(FORTRAN_ifcore_LIBRARY) + if (FORTRAN_ifcore_LIBRARY) + set(LGFORTRAN "{FORTRAN_ifcore_LIBRARY}") + endif() + endif() + set(BLAS_COMPILER_FLAGS "") + if (NOT BLA_VENDOR STREQUAL "Intel10_64lp_seq") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + list(APPEND BLAS_COMPILER_FLAGS "-openmp") + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + list(APPEND BLAS_COMPILER_FLAGS "-fopenmp") + endif() + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + if (BLA_VENDOR STREQUAL "Intel10_32") + list(APPEND BLAS_COMPILER_FLAGS "-m32") + else() + list(APPEND BLAS_COMPILER_FLAGS "-m64") + endif() + if (NOT BLA_VENDOR STREQUAL "Intel10_64lp_seq") + list(APPEND OMP_LIB "-ldl") + endif() + if (ENV_MKLROOT) + list(APPEND BLAS_COMPILER_FLAGS "-I${ENV_MKLROOT}/include") + endif() + endif() + + set(additional_flags "") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(additional_flags "-Wl,--no-as-needed") + endif() endif () if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) - if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED) - find_package(Threads) - else() - find_package(Threads REQUIRED) - endif() - - set(BLAS_SEARCH_LIBS "") - - if(BLA_F95) - - set(BLAS_mkl_SEARCH_SYMBOL SGEMM) - set(_LIBRARIES BLAS95_LIBRARIES) - if (WIN32) - if (BLA_STATIC) - set(BLAS_mkl_DLL_SUFFIX "") - else() - set(BLAS_mkl_DLL_SUFFIX "_dll") - endif() - - # Find the main file (32-bit or 64-bit) - set(BLAS_SEARCH_LIBS_WIN_MAIN "") - if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN - "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}") - endif() - if (BLA_VENDOR STREQUAL "Intel10_64lp*" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN - "mkl_blas95_lp64${BLAS_mkl_DLL_SUFFIX} mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}") - endif () - - # Add threading/sequential libs - set(BLAS_SEARCH_LIBS_WIN_THREAD "") - if (BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") - endif() - if (NOT BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") - # old version - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") - # mkl >= 10.3 - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") - endif() - - # Cartesian product of the above - foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN}) - foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD}) - list(APPEND BLAS_SEARCH_LIBS - "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}") - endforeach() - endforeach() - else (WIN32) - if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide") - endif () - if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") - # old version - list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide") - # mkl >= 10.3 - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") - list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core") - endif() - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - list(APPEND BLAS_SEARCH_LIBS - "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core") - endif() - endif () - if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_lp64 mkl_sequential mkl_core") - if (BLA_VENDOR STREQUAL "Intel10_64lp_seq") - set(OMP_LIB "") - endif() - endif () - endif (WIN32) - - else (BLA_F95) - - set(BLAS_mkl_SEARCH_SYMBOL sgemm) - set(_LIBRARIES BLAS_LIBRARIES) - if (WIN32) - if (BLA_STATIC) - set(BLAS_mkl_DLL_SUFFIX "") - else() - set(BLAS_mkl_DLL_SUFFIX "_dll") - endif() - - # Find the main file (32-bit or 64-bit) - set(BLAS_SEARCH_LIBS_WIN_MAIN "") - if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN - "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}") - endif() - if (BLA_VENDOR STREQUAL "Intel10_64lp*" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN - "mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}") - endif () - - # Add threading/sequential libs - set(BLAS_SEARCH_LIBS_WIN_THREAD "") - if (NOT BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") - # old version - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") - # mkl >= 10.3 - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") - endif() - if (BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD - "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") - endif() - - # Cartesian product of the above - foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN}) - foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD}) - list(APPEND BLAS_SEARCH_LIBS - "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}") - endforeach() - endforeach() - else (WIN32) - if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel mkl_intel_thread mkl_core guide") - endif () - if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") - # old version - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_lp64 mkl_intel_thread mkl_core guide") - # mkl >= 10.3 - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_lp64 mkl_intel_thread mkl_core") - endif() - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_lp64 mkl_gnu_thread mkl_core") - endif() - endif () - if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS - "mkl_intel_lp64 mkl_sequential mkl_core") - if (BLA_VENDOR STREQUAL "Intel10_64lp_seq") - set(OMP_LIB "") - endif() - endif () - #older vesions of intel mkl libs - if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All") - list(APPEND BLAS_SEARCH_LIBS - "mkl") - list(APPEND BLAS_SEARCH_LIBS - "mkl_ia32") - list(APPEND BLAS_SEARCH_LIBS - "mkl_em64t") - endif () - endif (WIN32) - - endif (BLA_F95) - - foreach (IT ${BLAS_SEARCH_LIBS}) - string(REPLACE " " ";" SEARCH_LIBS ${IT}) - if (${_LIBRARIES}) - else () - check_fortran_libraries( - ${_LIBRARIES} - BLAS - ${BLAS_mkl_SEARCH_SYMBOL} - "${additional_flags}" - "${SEARCH_LIBS}" - "${OMP_LIB};${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - if(_LIBRARIES) - set(BLAS_LINKER_FLAGS "${additional_flags}") - endif() - endif() - endforeach () + if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED) + find_package(Threads) + else() + find_package(Threads REQUIRED) + endif() + + set(BLAS_SEARCH_LIBS "") + + if(BLA_F95) + + set(BLAS_mkl_SEARCH_SYMBOL SGEMM) + set(_LIBRARIES BLAS95_LIBRARIES) + if (WIN32) + if (BLA_STATIC) + set(BLAS_mkl_DLL_SUFFIX "") + else() + set(BLAS_mkl_DLL_SUFFIX "_dll") + endif() + + # Find the main file (32-bit or 64-bit) + set(BLAS_SEARCH_LIBS_WIN_MAIN "") + if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN + "mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}") + endif() + if (BLA_VENDOR STREQUAL "Intel10_64lp*" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN + "mkl_blas95_lp64${BLAS_mkl_DLL_SUFFIX} mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}") + endif () + + # Add threading/sequential libs + set(BLAS_SEARCH_LIBS_WIN_THREAD "") + if (BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") + endif() + if (NOT BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") + # old version + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") + # mkl >= 10.3 + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") + endif() + + # Cartesian product of the above + foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN}) + foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD}) + list(APPEND BLAS_SEARCH_LIBS + "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}") + endforeach() + endforeach() + else (WIN32) + if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide") + endif () + if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") + # old version + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide") + # mkl >= 10.3 + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core") + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core") + endif() + endif () + if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_sequential mkl_core") + if (BLA_VENDOR STREQUAL "Intel10_64lp_seq") + set(OMP_LIB "") + endif() + endif () + endif (WIN32) + + else (BLA_F95) + + set(BLAS_mkl_SEARCH_SYMBOL sgemm) + set(_LIBRARIES BLAS_LIBRARIES) + if (WIN32) + if (BLA_STATIC) + set(BLAS_mkl_DLL_SUFFIX "") + else() + set(BLAS_mkl_DLL_SUFFIX "_dll") + endif() + + # Find the main file (32-bit or 64-bit) + set(BLAS_SEARCH_LIBS_WIN_MAIN "") + if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN + "mkl_intel_c${BLAS_mkl_DLL_SUFFIX}") + endif() + if (BLA_VENDOR STREQUAL "Intel10_64lp*" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN + "mkl_intel_lp64${BLAS_mkl_DLL_SUFFIX}") + endif () + + # Add threading/sequential libs + set(BLAS_SEARCH_LIBS_WIN_THREAD "") + if (NOT BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") + # old version + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") + # mkl >= 10.3 + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}") + endif() + if (BLA_VENDOR STREQUAL "*_seq" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD + "mkl_sequential${BLAS_mkl_DLL_SUFFIX}") + endif() + + # Cartesian product of the above + foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN}) + foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD}) + list(APPEND BLAS_SEARCH_LIBS + "${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}") + endforeach() + endforeach() + else (WIN32) + if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel mkl_intel_thread mkl_core guide") + endif () + if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") + # old version + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_intel_thread mkl_core guide") + # mkl >= 10.3 + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_intel_thread mkl_core") + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_gnu_thread mkl_core") + endif() + endif () + if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_sequential mkl_core") + if (BLA_VENDOR STREQUAL "Intel10_64lp_seq") + set(OMP_LIB "") + endif() + endif () + #older vesions of intel mkl libs + if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl") + list(APPEND BLAS_SEARCH_LIBS + "mkl_ia32") + list(APPEND BLAS_SEARCH_LIBS + "mkl_em64t") + endif () + endif (WIN32) + + endif (BLA_F95) + + foreach (IT ${BLAS_SEARCH_LIBS}) + string(REPLACE " " ";" SEARCH_LIBS ${IT}) + if (${_LIBRARIES}) + else () + check_fortran_libraries( + ${_LIBRARIES} + BLAS + ${BLAS_mkl_SEARCH_SYMBOL} + "${additional_flags}" + "${SEARCH_LIBS}" + "${OMP_LIB};${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + if(_LIBRARIES) + set(BLAS_LINKER_FLAGS "${additional_flags}") + endif() + endif() + endforeach () endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) + endif(NOT BLAS_LIBRARIES OR BLA_VENDOR MATCHES "Intel*") + + if(NOT BLAS_FIND_QUIETLY) + if(${_LIBRARIES}) + message(STATUS "Looking for MKL BLAS: found") + else() + message(STATUS "Looking for MKL BLAS: not found") + endif() + endif() endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "goto2" - "" - ) + if(NOT BLAS_LIBRARIES) + # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "goto2" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Goto BLAS: found") + else() + message(STATUS "Looking for Goto BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") @@ -725,17 +729,24 @@ endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") # OpenBlas if (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # openblas (http://www.openblas.net/) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "openblas" - "" - ) + if(NOT BLAS_LIBRARIES) + # openblas (http://www.openblas.net/) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "openblas" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Open BLAS: found") + else() + message(STATUS "Looking for Open BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All") @@ -743,46 +754,67 @@ endif (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All") # EigenBlas if (BLA_VENDOR STREQUAL "Eigen" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # eigenblas (http://eigen.tuxfamily.org/index.php?title=Main_Page) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "eigen_blas" - "" - ) + if(NOT BLAS_LIBRARIES) + # eigenblas (http://eigen.tuxfamily.org/index.php?title=Main_Page) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "eigen_blas" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Eigen BLAS: found") + else() + message(STATUS "Looking for Eigen BLAS: not found") + endif() endif() - - if(NOT BLAS_LIBRARIES) - # eigenblas (http://eigen.tuxfamily.org/index.php?title=Main_Page) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "eigen_blas_static" - "" - ) + endif() + + if(NOT BLAS_LIBRARIES) + # eigenblas (http://eigen.tuxfamily.org/index.php?title=Main_Page) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "eigen_blas_static" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Eigen BLAS: found") + else() + message(STATUS "Looking for Eigen BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "Eigen" OR BLA_VENDOR STREQUAL "All") if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - dgemm - "" - "f77blas;atlas" - "" - ) + if(NOT BLAS_LIBRARIES) + # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + dgemm + "" + "f77blas;atlas" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Atlas BLAS: found") + else() + message(STATUS "Looking for Atlas BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") @@ -790,16 +822,23 @@ endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All") # BLAS in PhiPACK libraries? (requires generic BLAS lib, too) if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "sgemm;dgemm;blas" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "sgemm;dgemm;blas" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for PhiPACK BLAS: found") + else() + message(STATUS "Looking for PhiPACK BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All") @@ -807,16 +846,23 @@ endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All") # BLAS in Alpha CXML library? if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "cxml" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "cxml" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for CXML BLAS: found") + else() + message(STATUS "Looking for CXML BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All") @@ -824,16 +870,23 @@ endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All") # BLAS in Alpha DXML library? (now called CXML, see above) if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "dxml" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "dxml" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for DXML BLAS: found") + else() + message(STATUS "Looking for DXML BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All") @@ -841,19 +894,26 @@ endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All") # BLAS in Sun Performance library? if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "-xlic_lib=sunperf" - "sunperf;sunmath" - "" - ) - if(BLAS_LIBRARIES) - set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf") - endif() + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "-xlic_lib=sunperf" + "sunperf;sunmath" + "" + ) + if(BLAS_LIBRARIES) + set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf") + endif() + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for SunPerf BLAS: found") + else() + message(STATUS "Looking for SunPerf BLAS: not found") + endif() endif() + endif() endif () @@ -861,16 +921,23 @@ endif () # BLAS in SCSL library? (SGI/Cray Scientific Library) if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "scsl" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "scsl" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for SCSL BLAS: found") + else() + message(STATUS "Looking for SCSL BLAS: not found") + endif() endif() + endif() endif () @@ -878,33 +945,70 @@ endif () # BLAS in SGIMATH library? if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "complib.sgimath" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "complib.sgimath" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for SGIMATH BLAS: found") + else() + message(STATUS "Looking for SGIMATH BLAS: not found") + endif() endif() + endif() endif () -# BLAS in IBM ESSL library? (requires generic BLAS lib, too) +# BLAS in IBM ESSL library (requires generic BLAS lib, too) if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "essl;blas" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "essl;xlfmath;xlf90_r;blas" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for IBM ESSL BLAS: found") + else() + message(STATUS "Looking for IBM ESSL BLAS: not found") + endif() + endif() + endif() + +endif () + +# BLAS in IBM ESSL_MT library (requires generic BLAS lib, too) +if (BLA_VENDOR STREQUAL "IBMESSLMT" OR BLA_VENDOR STREQUAL "All") + + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "esslsmp;xlsmp;xlfmath;xlf90_r;blas" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for IBM ESSL MT BLAS: found") + else() + message(STATUS "Looking for IBM ESSL MT BLAS: not found") + endif() endif() + endif() endif () @@ -912,147 +1016,168 @@ endif () #BLAS in acml library? if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") - if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR - ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR - ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))) - - # try to find acml in "standard" paths - if( WIN32 ) - file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" ) - else() - file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" ) - endif() - if( WIN32 ) - file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" ) - else() - file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" ) - endif() - list(GET _ACML_ROOT 0 _ACML_ROOT) - list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT) - - if( _ACML_ROOT ) - - get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH ) - if( SIZEOF_INTEGER EQUAL 8 ) - set( _ACML_PATH_SUFFIX "_int64" ) - else() - set( _ACML_PATH_SUFFIX "" ) - endif() - if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" ) - set( _ACML_COMPILER32 "ifort32" ) - set( _ACML_COMPILER64 "ifort64" ) - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" ) - set( _ACML_COMPILER32 "sun32" ) - set( _ACML_COMPILER64 "sun64" ) - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" ) - set( _ACML_COMPILER32 "pgi32" ) - if( WIN32 ) - set( _ACML_COMPILER64 "win64" ) - else() - set( _ACML_COMPILER64 "pgi64" ) - endif() - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" ) - # 32 bit builds not supported on Open64 but for code simplicity - # We'll just use the same directory twice - set( _ACML_COMPILER32 "open64_64" ) - set( _ACML_COMPILER64 "open64_64" ) - elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" ) - set( _ACML_COMPILER32 "nag32" ) - set( _ACML_COMPILER64 "nag64" ) - else() - set( _ACML_COMPILER32 "gfortran32" ) - set( _ACML_COMPILER64 "gfortran64" ) - endif() - - if( BLA_VENDOR STREQUAL "ACML_MP" ) - set(_ACML_MP_LIB_DIRS - "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib" - "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" ) - else() - set(_ACML_LIB_DIRS - "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib" - "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" ) - endif() - - endif(_ACML_ROOT) - - elseif(BLAS_${BLA_VENDOR}_LIB_DIRS) - - set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS}) + if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR + ((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR + ((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))) + # try to find acml in "standard" paths + if( WIN32 ) + file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" ) + else() + file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" ) endif() - - if( BLA_VENDOR STREQUAL "ACML_MP" ) - foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS}) - check_fortran_libraries ( - BLAS_LIBRARIES - BLAS - sgemm - "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} - ) - if( BLAS_LIBRARIES ) - break() - endif() - endforeach() - elseif( BLA_VENDOR STREQUAL "ACML_GPU" ) - foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS}) - check_fortran_libraries ( - BLAS_LIBRARIES - BLAS - sgemm - "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} - ) - if( BLAS_LIBRARIES ) - break() - endif() - endforeach() + if( WIN32 ) + file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" ) else() - foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} ) - check_fortran_libraries ( - BLAS_LIBRARIES - BLAS - sgemm - "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} - ) - if( BLAS_LIBRARIES ) - break() - endif() - endforeach() + file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" ) endif() - - # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "acml;acml_mv" - "" - ) + list(GET _ACML_ROOT 0 _ACML_ROOT) + list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT) + + if( _ACML_ROOT ) + + get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH ) + if( SIZEOF_INTEGER EQUAL 8 ) + set( _ACML_PATH_SUFFIX "_int64" ) + else() + set( _ACML_PATH_SUFFIX "" ) + endif() + if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" ) + set( _ACML_COMPILER32 "ifort32" ) + set( _ACML_COMPILER64 "ifort64" ) + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" ) + set( _ACML_COMPILER32 "sun32" ) + set( _ACML_COMPILER64 "sun64" ) + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" ) + set( _ACML_COMPILER32 "pgi32" ) + if( WIN32 ) + set( _ACML_COMPILER64 "win64" ) + else() + set( _ACML_COMPILER64 "pgi64" ) + endif() + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" ) + # 32 bit builds not supported on Open64 but for code simplicity + # We'll just use the same directory twice + set( _ACML_COMPILER32 "open64_64" ) + set( _ACML_COMPILER64 "open64_64" ) + elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" ) + set( _ACML_COMPILER32 "nag32" ) + set( _ACML_COMPILER64 "nag64" ) + else() + set( _ACML_COMPILER32 "gfortran32" ) + set( _ACML_COMPILER64 "gfortran64" ) + endif() + + if( BLA_VENDOR STREQUAL "ACML_MP" ) + set(_ACML_MP_LIB_DIRS + "${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib" + "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" ) + else() + set(_ACML_LIB_DIRS + "${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib" + "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" ) + endif() + + endif(_ACML_ROOT) + + elseif(BLAS_${BLA_VENDOR}_LIB_DIRS) + + set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS}) + + endif() + + if( BLA_VENDOR STREQUAL "ACML_MP" ) + foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS}) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + elseif( BLA_VENDOR STREQUAL "ACML_GPU" ) + foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS}) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + else() + foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} ) + check_fortran_libraries ( + BLAS_LIBRARIES + BLAS + sgemm + "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} + ) + if( BLAS_LIBRARIES ) + break() + endif() + endforeach() + endif() + + # Either acml or acml_mp should be in LD_LIBRARY_PATH but not both + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml;acml_mv" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for ACML BLAS: found") + else() + message(STATUS "Looking for ACML BLAS: not found") + endif() endif() - - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "acml_mp;acml_mv" - "" - ) + endif() + + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml_mp;acml_mv" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for ACML BLAS: found") + else() + message(STATUS "Looking for ACML BLAS: not found") + endif() endif() - - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "acml;acml_mv;CALBLAS" - "" - ) + endif() + + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml;acml_mv;CALBLAS" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for ACML BLAS: found") + else() + message(STATUS "Looking for ACML BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") # ACML @@ -1060,32 +1185,47 @@ endif (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") # ACML # Apple BLAS library? if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - dgemm - "" - "Accelerate" - "" - ) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + dgemm + "" + "Accelerate" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Apple BLAS: found") + else() + message(STATUS "Looking for Apple BLAS: not found") + endif() endif() + endif() endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") - if ( NOT BLAS_LIBRARIES ) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - dgemm - "" - "vecLib" - "" - ) - endif () + if ( NOT BLAS_LIBRARIES ) + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + dgemm + "" + "vecLib" + "" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for NAS BLAS: found") + else() + message(STATUS "Looking for NAS BLAS: not found") + endif() + endif() + endif () + endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") @@ -1093,108 +1233,116 @@ endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") # Generic BLAS library? if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") - set(BLAS_SEARCH_LIBS "blas;blas_LINUX;blas_MAC;blas_WINDOWS") - foreach (SEARCH_LIB ${BLAS_SEARCH_LIBS}) - if (BLAS_LIBRARIES) - else () - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "${SEARCH_LIB}" - "${LGFORTRAN}" - ) - endif() - endforeach () + set(BLAS_SEARCH_LIBS "blas;blas_LINUX;blas_MAC;blas_WINDOWS;refblas") + foreach (SEARCH_LIB ${BLAS_SEARCH_LIBS}) + if (BLAS_LIBRARIES) + else () + check_fortran_libraries( + BLAS_LIBRARIES + BLAS + sgemm + "" + "${SEARCH_LIB}" + "${LGFORTRAN}" + ) + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + message(STATUS "Looking for Generic BLAS: found") + else() + message(STATUS "Looking for Generic BLAS: not found") + endif() + endif() + endif() + endforeach () endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All") if(BLA_F95) - if(BLAS95_LIBRARIES) - set(BLAS95_FOUND TRUE) - else() - set(BLAS95_FOUND FALSE) - endif() - - if(NOT BLAS_FIND_QUIETLY) - if(BLAS95_FOUND) - message(STATUS "A library with BLAS95 API found.") - message(STATUS "BLAS_LIBRARIES ${BLAS_LIBRARIES}") - else(BLAS95_FOUND) - message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but blas 95 libraries could not be found or check of symbols failed." - "\nPlease indicate where to find blas libraries. You have three options:\n" - "- Option 1: Provide the installation directory of BLAS library with cmake option: -DBLAS_DIR=your/path/to/blas\n" - "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "\nTo follow libraries detection more precisely you can activate a verbose mode with -DBLAS_VERBOSE=ON at cmake configure." - "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." - "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," - "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," - "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") - if(BLAS_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with BLAS95 API not found. Please specify library location.") - else() - message(STATUS - "A library with BLAS95 API not found. Please specify library location.") - endif() - endif(BLAS95_FOUND) - endif(NOT BLAS_FIND_QUIETLY) - - set(BLAS_FOUND TRUE) - set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}") - if (NOT BLAS_LIBRARIES_DEP) - set(BLAS_LIBRARIES_DEP "${BLAS95_LIBRARIES}") - endif() + if(BLAS95_LIBRARIES) + set(BLAS95_FOUND TRUE) + else() + set(BLAS95_FOUND FALSE) + endif() + + if(NOT BLAS_FIND_QUIETLY) + if(BLAS95_FOUND) + message(STATUS "A library with BLAS95 API found.") + message(STATUS "BLAS_LIBRARIES ${BLAS_LIBRARIES}") + else(BLAS95_FOUND) + message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but blas 95 libraries could not be found or check of symbols failed." + "\nPlease indicate where to find blas libraries. You have three options:\n" + "- Option 1: Provide the installation directory of BLAS library with cmake option: -DBLAS_DIR=your/path/to/blas\n" + "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "\nTo follow libraries detection more precisely you can activate a verbose mode with -DBLAS_VERBOSE=ON at cmake configure." + "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." + "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," + "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," + "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with BLAS95 API not found. Please specify library location.") + else() + message(STATUS + "A library with BLAS95 API not found. Please specify library location.") + endif() + endif(BLAS95_FOUND) + endif(NOT BLAS_FIND_QUIETLY) + + set(BLAS_FOUND TRUE) + set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}") + if (NOT BLAS_LIBRARIES_DEP) + set(BLAS_LIBRARIES_DEP "${BLAS95_LIBRARIES}") + endif() else(BLA_F95) - if(BLAS_LIBRARIES) - set(BLAS_FOUND TRUE) - else() - set(BLAS_FOUND FALSE) - endif() - - if(NOT BLAS_FIND_QUIETLY) - if(BLAS_FOUND) - message(STATUS "A library with BLAS API found.") - message(STATUS "BLAS_LIBRARIES ${BLAS_LIBRARIES}") - else(BLAS_FOUND) - message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but blas libraries could not be found or check of symbols failed." - "\nPlease indicate where to find blas libraries. You have three options:\n" - "- Option 1: Provide the installation directory of BLAS library with cmake option: -DBLAS_DIR=your/path/to/blas\n" - "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "\nTo follow libraries detection more precisely you can activate a verbose mode with -DBLAS_VERBOSE=ON at cmake configure." - "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." - "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," - "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," - "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") - if(BLAS_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with BLAS API not found. Please specify library location.") - else() - message(STATUS - "A library with BLAS API not found. Please specify library location.") - endif() - endif(BLAS_FOUND) - endif(NOT BLAS_FIND_QUIETLY) + if(BLAS_LIBRARIES) + set(BLAS_FOUND TRUE) + else() + set(BLAS_FOUND FALSE) + endif() + + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_FOUND) + message(STATUS "A library with BLAS API found.") + message(STATUS "BLAS_LIBRARIES ${BLAS_LIBRARIES}") + else(BLAS_FOUND) + message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but blas libraries could not be found or check of symbols failed." + "\nPlease indicate where to find blas libraries. You have three options:\n" + "- Option 1: Provide the installation directory of BLAS library with cmake option: -DBLAS_DIR=your/path/to/blas\n" + "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "\nTo follow libraries detection more precisely you can activate a verbose mode with -DBLAS_VERBOSE=ON at cmake configure." + "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." + "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," + "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," + "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with BLAS API not found. Please specify library location.") + else() + message(STATUS + "A library with BLAS API not found. Please specify library location.") + endif() + endif(BLAS_FOUND) + endif(NOT BLAS_FIND_QUIETLY) endif(BLA_F95) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) if (BLAS_FOUND) - list(GET BLAS_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") - string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") - set(BLAS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of BLAS library" FORCE) - else() - set(BLAS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of BLAS library" FORCE) - endif() + list(GET BLAS_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") + string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") + set(BLAS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of BLAS library" FORCE) + else() + set(BLAS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of BLAS library" FORCE) + endif() endif() - +mark_as_advanced(BLAS_DIR) +mark_as_advanced(BLAS_DIR_FOUND) diff --git a/CMakeModules/morse/find/FindBLASEXT.cmake b/CMakeModules/morse/find/FindBLASEXT.cmake index f13b6c9fc64cd3be0c4bf13eb5d29ba52474e83a..0fe7fb84931bacf4f7879be412c6abf37c44d175 100644 --- a/CMakeModules/morse/find/FindBLASEXT.cmake +++ b/CMakeModules/morse/find/FindBLASEXT.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -13,8 +13,8 @@ # This module allows to find BLAS libraries by calling the official FindBLAS module # and handles the creation of different library lists whether the user wishes to link # with a sequential BLAS or a multihreaded (BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES). -# BLAS is detected with a FindBLAS call then if the BLAS vendor is Intel10_64lp or ACML -# then the module tries to find the corresponding multithreaded libraries. +# BLAS is detected with a FindBLAS call then if the BLAS vendor is Intel10_64lp, ACML +# or IBMESSLMT then the module attempts to find the corresponding multithreaded libraries. # # The following variables have been added to manage links with sequential or multithreaded # versions: @@ -28,7 +28,7 @@ # Copyright 2012-2013 Emmanuel Agullo # Copyright 2012-2013 Mathieu Faverge # Copyright 2012 Cedric Castagnede -# Copyright 2013 Florent Pruvost +# Copyright 2013-2016 Florent Pruvost # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file MORSE-Copyright.txt for details. @@ -40,296 +40,341 @@ # (To distribute this file outside of Morse, substitute the full # License text for the above reference.) +# macro to factorize this call +macro(find_package_blas) + if(BLASEXT_FIND_REQUIRED) + if(BLASEXT_FIND_QUIETLY) + find_package(BLAS REQUIRED QUIET) + else() + find_package(BLAS REQUIRED) + endif() + else() + if(BLASEXT_FIND_QUIETLY) + find_package(BLAS QUIET) + else() + find_package(BLAS) + endif() + endif() +endmacro() # add a cache variable to let the user specify the BLAS vendor set(BLA_VENDOR "" CACHE STRING "list of possible BLAS vendor: - Open, Eigen, Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, + Open, Eigen, Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, Intel10_32 (intel mkl v10 32 bit), Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model), Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") +if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "In FindBLASEXT") + message(STATUS "If you want to force the use of one specific library, " + "\n please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name" + "\n at cmake configure.") + message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, " + "\n DXML, SunPerf, SCSL, SGIMATH, IBMESSL, IBMESSLMT, Intel10_32 (intel mkl v10 32 bit)," + "\n Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model)," + "\n Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," + "\n Intel( older versions of mkl 32 and 64 bit)," + "\n ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") +endif() if (NOT BLAS_FOUND) - # First try to detect two cases: - # 1: only SEQ libs are handled - # 2: both SEQ and PAR libs are handled - if(BLASEXT_FIND_REQUIRED) - find_package(BLAS REQUIRED) - else() - find_package(BLAS) - endif() + # First try to detect two cases: + # 1: only SEQ libs are handled + # 2: both SEQ and PAR libs are handled + find_package_blas() endif () # detect the cases where SEQ and PAR libs are handled if(BLA_VENDOR STREQUAL "All" AND - (BLAS_mkl_core_LIBRARY OR BLAS_mkl_core_dll_LIBRARY) - ) - set(BLA_VENDOR "Intel") - if(BLAS_mkl_intel_LIBRARY) - set(BLA_VENDOR "Intel10_32") - endif() - if(BLAS_mkl_intel_lp64_LIBRARY) - set(BLA_VENDOR "Intel10_64lp") - endif() - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" - "have also potentially detected some BLAS libraries from the MKL." - "We try to use this one.") - message(STATUS "If you want to force the use of one specific library, " - "please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name" - "at cmake configure.") - message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, " - "DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," - "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model)," - "Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," - "Intel( older versions of mkl 32 and 64 bit)," - "ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") - endif() - set(BLAS_FOUND "") + (BLAS_mkl_core_LIBRARY OR BLAS_mkl_core_dll_LIBRARY) + ) + set(BLA_VENDOR "Intel") + if(BLAS_mkl_intel_LIBRARY) + set(BLA_VENDOR "Intel10_32") + endif() + if(BLAS_mkl_intel_lp64_LIBRARY) + set(BLA_VENDOR "Intel10_64lp") + endif() + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" + "\n have also potentially detected some multithreaded BLAS libraries from the MKL." + "\n We try to find both libraries lists (Sequential/Multithreaded).") + endif() + set(BLAS_FOUND "") elseif(BLA_VENDOR STREQUAL "All" AND BLAS_acml_LIBRARY) - set(BLA_VENDOR "ACML") - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" - "have also potentially detected some BLAS libraries from the ACML." - "We try to use this one.") - message(STATUS "If you want to force the use of one specific library, " - "please specify the BLAS vendor by setting -DBLA_VENDOR=blas_vendor_name" - "at cmake configure.") - message(STATUS "List of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, " - "DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," - "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model)," - "Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," - "Intel( older versions of mkl 32 and 64 bit)," - "ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") - endif() - set(BLAS_FOUND "") + set(BLA_VENDOR "ACML") + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" + "\n have also potentially detected some multithreaded BLAS libraries from the ACML." + "\n We try to find both libraries lists (Sequential/Multithreaded).") + endif() + set(BLAS_FOUND "") +elseif(BLA_VENDOR STREQUAL "All" AND BLAS_essl_LIBRARY) + set(BLA_VENDOR "IBMESSL") + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "A BLAS library has been found (${BLAS_LIBRARIES}) but we" + "\n have also potentially detected some multithreaded BLAS libraries from the ESSL." + "\n We try to find both libraries lists (Sequential/Multithreaded).") + endif() + set(BLAS_FOUND "") endif() # Intel case if(BLA_VENDOR MATCHES "Intel*") - ### - # look for include path if the BLAS vendor is Intel - ### + ### + # look for include path if the BLAS vendor is Intel + ### - # gather system include paths - unset(_inc_env) - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) + # gather system include paths + unset(_inc_env) + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + set(ENV_MKLROOT "$ENV{MKLROOT}") + if (ENV_MKLROOT) + list(APPEND _inc_env "${ENV_MKLROOT}/include") + endif() + list(REMOVE_DUPLICATES _inc_env) - # find mkl.h inside known include paths + # find mkl.h inside known include paths + set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") + if(BLAS_INCDIR) set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") - if(BLAS_INCDIR) - set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") - find_path(BLAS_mkl.h_INCLUDE_DIRS - NAMES mkl.h - HINTS ${BLAS_INCDIR}) + find_path(BLAS_mkl.h_INCLUDE_DIRS + NAMES mkl.h + HINTS ${BLAS_INCDIR}) + else() + if(BLAS_DIR) + set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") + find_path(BLAS_mkl.h_INCLUDE_DIRS + NAMES mkl.h + HINTS ${BLAS_DIR} + PATH_SUFFIXES include) else() - if(BLAS_DIR) - set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") - find_path(BLAS_mkl.h_INCLUDE_DIRS - NAMES mkl.h - HINTS ${BLAS_DIR} - PATH_SUFFIXES include) - else() - set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") - find_path(BLAS_mkl.h_INCLUDE_DIRS - NAMES mkl.h - HINTS ${_inc_env}) - endif() + set(BLAS_mkl.h_INCLUDE_DIRS "BLAS_mkl.h_INCLUDE_DIRS-NOTFOUND") + find_path(BLAS_mkl.h_INCLUDE_DIRS + NAMES mkl.h + HINTS ${_inc_env}) endif() - mark_as_advanced(BLAS_mkl.h_INCLUDE_DIRS) - ## Print status if not found - ## ------------------------- - #if (NOT BLAS_mkl.h_INCLUDE_DIRS AND MORSE_VERBOSE) - # Print_Find_Header_Status(blas mkl.h) - #endif () - set(BLAS_INCLUDE_DIRS "") - if(BLAS_mkl.h_INCLUDE_DIRS) - list(APPEND BLAS_INCLUDE_DIRS "${BLAS_mkl.h_INCLUDE_DIRS}" ) - endif() - - ### - # look for libs - ### - # if Intel 10 64 bit -> look for sequential and multithreaded versions - if(BLA_VENDOR MATCHES "Intel10_64lp*") - - ## look for the sequential version - set(BLA_VENDOR "Intel10_64lp_seq") - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "Look for the sequential version Intel10_64lp_seq") - endif() -# if(NOT BLAS_FOUND AND BLASEXT_FIND_REQUIRED) - if(BLASEXT_FIND_REQUIRED) - find_package(BLAS REQUIRED) - else() - find_package(BLAS) - endif() - if(BLAS_FOUND) - set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") - else() - set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") - endif() - - ## look for the multithreaded version - set(BLA_VENDOR "Intel10_64lp") - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "Look for the multithreaded version Intel10_64lp") - endif() - find_package(BLAS) - if(BLAS_FOUND) - set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") - else() - set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") - endif() - - else() - - if(BLAS_FOUND) - set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") - else() - set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") - endif() + endif() + mark_as_advanced(BLAS_mkl.h_INCLUDE_DIRS) + ## Print status if not found + ## ------------------------- + #if (NOT BLAS_mkl.h_INCLUDE_DIRS AND MORSE_VERBOSE) + # Print_Find_Header_Status(blas mkl.h) + #endif () + set(BLAS_INCLUDE_DIRS "") + if(BLAS_mkl.h_INCLUDE_DIRS) + list(APPEND BLAS_INCLUDE_DIRS "${BLAS_mkl.h_INCLUDE_DIRS}" ) + endif() - endif() - -# ACML case -elseif(BLA_VENDOR MATCHES "ACML*") + ### + # look for libs + ### + # if Intel 10 64 bit -> look for sequential and multithreaded versions + if(BLA_VENDOR MATCHES "Intel10_64lp*") ## look for the sequential version - set(BLA_VENDOR "ACML") - if(BLASEXT_FIND_REQUIRED) - find_package(BLAS REQUIRED) - else() - find_package(BLAS) + set(BLA_VENDOR "Intel10_64lp_seq") + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "Look for the sequential version Intel10_64lp_seq") endif() + find_package_blas() if(BLAS_FOUND) - set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") + set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") else() - set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") + set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") endif() ## look for the multithreaded version - set(BLA_VENDOR "ACML_MP") - if(BLASEXT_FIND_REQUIRED) - find_package(BLAS REQUIRED) - else(BLAS_FOUND) - find_package(BLAS) + set(BLA_VENDOR "Intel10_64lp") + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "Look for the multithreaded version Intel10_64lp") endif() + find_package_blas() if(BLAS_FOUND) - set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") + set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") else() - set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") + set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") endif() -else() + else() if(BLAS_FOUND) - # define the SEQ libs as the BLAS_LIBRARIES - set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") + set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") else() - set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") + set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") endif() + + endif() + + # ACML case +elseif(BLA_VENDOR MATCHES "ACML*") + + ## look for the sequential version + set(BLA_VENDOR "ACML") + find_package_blas() + if(BLAS_FOUND) + set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") + else() + set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") + endif() + + ## look for the multithreaded version + set(BLA_VENDOR "ACML_MP") + find_package_blas() + if(BLAS_FOUND) + set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") + else() + set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") + endif() + + # IBMESSL case +elseif(BLA_VENDOR MATCHES "IBMESSL*") + + ## look for the sequential version + set(BLA_VENDOR "IBMESSL") + find_package_blas() + if(BLAS_FOUND) + set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") + else() + set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") + endif() + + ## look for the multithreaded version + set(BLA_VENDOR "IBMESSLMT") + find_package_blas() + if(BLAS_FOUND) + set(BLAS_PAR_LIBRARIES "${BLAS_LIBRARIES}") + else() set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") + endif() + +else() + + if(BLAS_FOUND) + # define the SEQ libs as the BLAS_LIBRARIES + set(BLAS_SEQ_LIBRARIES "${BLAS_LIBRARIES}") + else() + set(BLAS_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES-NOTFOUND}") + endif() + set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") endif() if(BLAS_SEQ_LIBRARIES) - set(BLAS_LIBRARIES "${BLAS_SEQ_LIBRARIES}") + set(BLAS_LIBRARIES "${BLAS_SEQ_LIBRARIES}") endif() -# message("DEBUG BLAS: ${BLAS_SEQ_LIBRARIES} ${BLAS_LIBRARIES}") # extract libs paths # remark: because it is not given by find_package(BLAS) set(BLAS_LIBRARY_DIRS "") +string(REPLACE " " ";" BLAS_LIBRARIES "${BLAS_LIBRARIES}") foreach(blas_lib ${BLAS_LIBRARIES}) + if (EXISTS "${blas_lib}") get_filename_component(a_blas_lib_dir "${blas_lib}" PATH) list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" ) + else() + string(REPLACE "-L" "" blas_lib "${blas_lib}") + if (EXISTS "${blas_lib}") + list(APPEND BLAS_LIBRARY_DIRS "${blas_lib}" ) + else() + get_filename_component(a_blas_lib_dir "${blas_lib}" PATH) + if (EXISTS "${a_blas_lib_dir}") + list(APPEND BLAS_LIBRARY_DIRS "${a_blas_lib_dir}" ) + endif() + endif() + endif() endforeach() if (BLAS_LIBRARY_DIRS) - list(REMOVE_DUPLICATES BLAS_LIBRARY_DIRS) + list(REMOVE_DUPLICATES BLAS_LIBRARY_DIRS) endif () - -# message(STATUS "BLAS_FOUND: ${BLAS_FOUND}") -# message(STATUS "BLA_VENDOR: ${BLA_VENDOR}") -# message(STATUS "BLAS_LIBRARIES: ${BLAS_LIBRARIES}") -# message(STATUS "BLAS_SEQ_LIBRARIES: ${BLAS_SEQ_LIBRARIES}") -# message(STATUS "BLAS_PAR_LIBRARIES: ${BLAS_PAR_LIBRARIES}") -# message(STATUS "BLAS_INCLUDE_DIRS: ${BLAS_INCLUDE_DIRS}") -# message(STATUS "BLAS_LIBRARY_DIRS: ${BLAS_LIBRARY_DIRS}") - # check that BLAS has been found # --------------------------------- include(FindPackageHandleStandardArgs) if(BLA_VENDOR MATCHES "Intel*") - if(BLA_VENDOR MATCHES "Intel10_64lp*") - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "BLAS found is Intel MKL:" - "we manage two lists of libs," - " one sequential and one parallel if found (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") - message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") - endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG - BLAS_SEQ_LIBRARIES - BLAS_LIBRARY_DIRS - BLAS_INCLUDE_DIRS) - if(BLAS_PAR_LIBRARIES) - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") - endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG - BLAS_PAR_LIBRARIES) - endif() - else() - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") - endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG - BLAS_SEQ_LIBRARIES - BLAS_LIBRARY_DIRS - BLAS_INCLUDE_DIRS) - endif() -elseif(BLA_VENDOR MATCHES "ACML*") + if(BLA_VENDOR MATCHES "Intel10_64lp*") if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "BLAS found is ACML:" - "we manage two lists of libs," - " one sequential and one parallel if found (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") - message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") + message(STATUS "BLAS found is Intel MKL:" + "\n we manage two lists of libs, one sequential and one parallel if found" + "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") + message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") endif() find_package_handle_standard_args(BLAS DEFAULT_MSG - BLAS_SEQ_LIBRARIES - BLAS_LIBRARY_DIRS - BLAS_INCLUDE_DIRS) + BLAS_SEQ_LIBRARIES + BLAS_LIBRARY_DIRS + BLAS_INCLUDE_DIRS) if(BLAS_PAR_LIBRARIES) - if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") - endif() - find_package_handle_standard_args(BLAS DEFAULT_MSG - BLAS_PAR_LIBRARIES) + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") + endif() + find_package_handle_standard_args(BLAS DEFAULT_MSG + BLAS_PAR_LIBRARIES) endif() -else() + else() + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(BLAS DEFAULT_MSG + BLAS_SEQ_LIBRARIES + BLAS_LIBRARY_DIRS + BLAS_INCLUDE_DIRS) + endif() +elseif(BLA_VENDOR MATCHES "ACML*") + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "BLAS found is ACML:" + "\n we manage two lists of libs, one sequential and one parallel if found" + "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") + message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(BLAS DEFAULT_MSG + BLAS_SEQ_LIBRARIES + BLAS_LIBRARY_DIRS) + if(BLAS_PAR_LIBRARIES) if(NOT BLASEXT_FIND_QUIETLY) - message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") + message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") endif() find_package_handle_standard_args(BLAS DEFAULT_MSG - BLAS_SEQ_LIBRARIES - BLAS_LIBRARY_DIRS) + BLAS_PAR_LIBRARIES) + endif() +elseif(BLA_VENDOR MATCHES "IBMESSL*") + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "BLAS found is ESSL:" + "\n we manage two lists of libs, one sequential and one parallel if found" + "\n (see BLAS_SEQ_LIBRARIES and BLAS_PAR_LIBRARIES)") + message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(BLAS DEFAULT_MSG + BLAS_SEQ_LIBRARIES + BLAS_LIBRARY_DIRS) + if(BLAS_PAR_LIBRARIES) + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "BLAS parallel libraries stored in BLAS_PAR_LIBRARIES") + endif() + find_package_handle_standard_args(BLAS DEFAULT_MSG + BLAS_PAR_LIBRARIES) + endif() +else() + if(NOT BLASEXT_FIND_QUIETLY) + message(STATUS "BLAS sequential libraries stored in BLAS_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(BLAS DEFAULT_MSG + BLAS_SEQ_LIBRARIES + BLAS_LIBRARY_DIRS) endif() diff --git a/CMakeModules/morse/find/FindCBLAS.cmake b/CMakeModules/morse/find/FindCBLAS.cmake index 0d080d5f522a3bb32e260a7e5d870990aa10b854..eb10586376230fd464c57ad49944d422ef8adcc8 100644 --- a/CMakeModules/morse/find/FindCBLAS.cmake +++ b/CMakeModules/morse/find/FindCBLAS.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -18,11 +18,6 @@ # CBLAS depends on the following libraries: # - BLAS # -# COMPONENTS are optional libraries LAPACKE could be linked with, -# Use it to drive detection of a specific compilation chain -# COMPONENTS can be some of the following: -# - BLASEXT: to activate detection of BLAS with BLASEXT cmake module -# # This module finds headers and cblas library. # Results are reported in variables: # CBLAS_FOUND - True if headers and requested libraries were found @@ -33,6 +28,7 @@ # CBLAS_INCLUDE_DIRS_DEP - cblas + dependencies include directories # CBLAS_LIBRARY_DIRS_DEP - cblas + dependencies link directories # CBLAS_LIBRARIES_DEP - cblas libraries + dependencies +# CBLAS_HAS_ZGEMM3M - True if cblas contains zgemm3m fast complex mat-mat product # # The user can give specific paths where to find the libraries adding cmake # options at configure (ex: cmake path/to/project -DCBLAS_DIR=path/to/cblas): @@ -67,7 +63,7 @@ # Copyright 2012-2013 Emmanuel Agullo # Copyright 2012-2013 Mathieu Faverge # Copyright 2012 Cedric Castagnede -# Copyright 2013 Florent Pruvost +# Copyright 2013-2016 Florent Pruvost # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file MORSE-Copyright.txt for details. @@ -81,311 +77,312 @@ if (NOT CBLAS_FOUND) - set(CBLAS_DIR "" CACHE PATH "Installation directory of CBLAS library") - if (NOT CBLAS_FIND_QUIETLY) - message(STATUS "A cache variable, namely CBLAS_DIR, has been set to specify the install directory of CBLAS") - endif() + set(CBLAS_DIR "" CACHE PATH "Installation directory of CBLAS library") + if (NOT CBLAS_FIND_QUIETLY) + message(STATUS "A cache variable, namely CBLAS_DIR, has been set to specify the install directory of CBLAS") + endif() endif() -# CBLAS may depend on BLASEXT -# try to find it specified as COMPONENTS during the call -if (CBLAS_FIND_COMPONENTS) - foreach( component ${CBLAS_FIND_COMPONENTS} ) - if(CBLAS_FIND_REQUIRED_${component}) - find_package(${component} REQUIRED) - else() - find_package(${component}) - endif() - if(${component}_FOUND) - set(CBLAS_${component}_FOUND TRUE) - else() - set(CBLAS_${component}_FOUND FALSE) - endif() - endforeach() -endif () - - # CBLAS depends on BLAS anyway, try to find it if (NOT BLAS_FOUND) - if(CBLAS_FIND_REQUIRED) - find_package(BLAS REQUIRED) - else() - find_package(BLAS) - endif() + if(CBLAS_FIND_REQUIRED) + find_package(BLASEXT REQUIRED) + else() + find_package(BLASEXT) + endif() endif() # find CBLAS if (BLAS_FOUND) - if (NOT CBLAS_STANDALONE) - # check if a cblas function exists in the BLAS lib - # this can be the case with libs such as MKL, ACML - include(CheckFunctionExists) - set(CMAKE_REQUIRED_LIBRARIES "${BLAS_LINKER_FLAGS};${BLAS_LIBRARIES}") - unset(CBLAS_WORKS CACHE) - check_function_exists(cblas_dscal CBLAS_WORKS) - mark_as_advanced(CBLAS_WORKS) - set(CMAKE_REQUIRED_LIBRARIES) - - if(CBLAS_WORKS) - if(NOT CBLAS_FIND_QUIETLY) - message(STATUS "Looking for cblas: test with blas succeeds") - endif() - # test succeeds: CBLAS is in BLAS - set(CBLAS_LIBRARIES "${BLAS_LIBRARIES}") - if (BLAS_LIBRARY_DIRS) - set(CBLAS_LIBRARY_DIRS "${BLAS_LIBRARY_DIRS}") - endif() - if(BLAS_INCLUDE_DIRS) - set(CBLAS_INCLUDE_DIRS "${BLAS_INCLUDE_DIRS}") - endif() - if (BLAS_LINKER_FLAGS) - set(CBLAS_LINKER_FLAGS "${BLAS_LINKER_FLAGS}") - endif() - endif() - endif (NOT CBLAS_STANDALONE) - - if (CBLAS_STANDALONE OR NOT CBLAS_WORKS) - - if(NOT CBLAS_WORKS AND NOT CBLAS_FIND_QUIETLY) - message(STATUS "Looking for cblas : test with blas fails") - endif() - # test fails: try to find CBLAS lib exterior to BLAS - - # Try to find CBLAS lib - ####################### - - # Looking for include - # ------------------- - - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - set(ENV_CBLAS_DIR "$ENV{CBLAS_DIR}") - set(ENV_CBLAS_INCDIR "$ENV{CBLAS_INCDIR}") - if(ENV_CBLAS_INCDIR) - list(APPEND _inc_env "${ENV_CBLAS_INCDIR}") - elseif(ENV_CBLAS_DIR) - list(APPEND _inc_env "${ENV_CBLAS_DIR}") - list(APPEND _inc_env "${ENV_CBLAS_DIR}/include") - list(APPEND _inc_env "${ENV_CBLAS_DIR}/include/cblas") - else() - if(WIN32) - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() - endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) - - - # Try to find the cblas header in the given paths - # ------------------------------------------------- - # call cmake macro to find the header path - if(CBLAS_INCDIR) - set(CBLAS_cblas.h_DIRS "CBLAS_cblas.h_DIRS-NOTFOUND") - find_path(CBLAS_cblas.h_DIRS - NAMES cblas.h - HINTS ${CBLAS_INCDIR}) - else() - if(CBLAS_DIR) - set(CBLAS_cblas.h_DIRS "CBLAS_cblas.h_DIRS-NOTFOUND") - find_path(CBLAS_cblas.h_DIRS - NAMES cblas.h - HINTS ${CBLAS_DIR} - PATH_SUFFIXES "include" "include/cblas") - else() - set(CBLAS_cblas.h_DIRS "CBLAS_cblas.h_DIRS-NOTFOUND") - find_path(CBLAS_cblas.h_DIRS - NAMES cblas.h - HINTS ${_inc_env} - PATH_SUFFIXES "cblas") - endif() - endif() - mark_as_advanced(CBLAS_cblas.h_DIRS) - - # If found, add path to cmake variable - # ------------------------------------ - if (CBLAS_cblas.h_DIRS) - set(CBLAS_INCLUDE_DIRS "${CBLAS_cblas.h_DIRS}") - else () - set(CBLAS_INCLUDE_DIRS "CBLAS_INCLUDE_DIRS-NOTFOUND") - if(NOT CBLAS_FIND_QUIETLY) - message(STATUS "Looking for cblas -- cblas.h not found") - endif() - endif() - - - # Looking for lib - # --------------- - - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - set(ENV_CBLAS_LIBDIR "$ENV{CBLAS_LIBDIR}") - if(ENV_CBLAS_LIBDIR) - list(APPEND _lib_env "${ENV_CBLAS_LIBDIR}") - elseif(ENV_CBLAS_DIR) - list(APPEND _lib_env "${ENV_CBLAS_DIR}") - list(APPEND _lib_env "${ENV_CBLAS_DIR}/lib") - else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() - endif() - list(REMOVE_DUPLICATES _lib_env) - - # Try to find the cblas lib in the given paths - # ---------------------------------------------- - - # call cmake macro to find the lib path - if(CBLAS_LIBDIR) - set(CBLAS_cblas_LIBRARY "CBLAS_cblas_LIBRARY-NOTFOUND") - find_library(CBLAS_cblas_LIBRARY - NAMES cblas - HINTS ${CBLAS_LIBDIR}) - else() - if(CBLAS_DIR) - set(CBLAS_cblas_LIBRARY "CBLAS_cblas_LIBRARY-NOTFOUND") - find_library(CBLAS_cblas_LIBRARY - NAMES cblas - HINTS ${CBLAS_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(CBLAS_cblas_LIBRARY "CBLAS_cblas_LIBRARY-NOTFOUND") - find_library(CBLAS_cblas_LIBRARY - NAMES cblas - HINTS ${_lib_env}) - endif() - endif() - mark_as_advanced(CBLAS_cblas_LIBRARY) - - # If found, add path to cmake variable - # ------------------------------------ - if (CBLAS_cblas_LIBRARY) - get_filename_component(cblas_lib_path "${CBLAS_cblas_LIBRARY}" PATH) - # set cmake variables - set(CBLAS_LIBRARIES "${CBLAS_cblas_LIBRARY}") - set(CBLAS_LIBRARY_DIRS "${cblas_lib_path}") - else () - set(CBLAS_LIBRARIES "CBLAS_LIBRARIES-NOTFOUND") - set(CBLAS_LIBRARY_DIRS "CBLAS_LIBRARY_DIRS-NOTFOUND") - if (NOT CBLAS_FIND_QUIETLY) - message(STATUS "Looking for cblas -- lib cblas not found") - endif() - endif () - - # check a function to validate the find - if(CBLAS_LIBRARIES) - - set(REQUIRED_INCDIRS) - set(REQUIRED_LDFLAGS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) - - # CBLAS - if (CBLAS_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS}") - endif() - if (CBLAS_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${CBLAS_LIBRARIES}") - # BLAS - if (BLAS_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${BLAS_INCLUDE_DIRS}") - endif() - if (BLAS_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${BLAS_LIBRARY_DIRS}") - endif() - list(APPEND REQUIRED_LIBS "${BLAS_LIBRARIES}") - if (BLAS_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") - endif() - - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - - # test link - unset(CBLAS_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(cblas_dscal CBLAS_WORKS) - mark_as_advanced(CBLAS_WORKS) - - if(CBLAS_WORKS) - # save link with dependencies - set(CBLAS_LIBRARIES_DEP "${REQUIRED_LIBS}") - set(CBLAS_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") - set(CBLAS_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") - set(CBLAS_LINKER_FLAGS "${REQUIRED_LDFLAGS}") - list(REMOVE_DUPLICATES CBLAS_LIBRARY_DIRS_DEP) - list(REMOVE_DUPLICATES CBLAS_INCLUDE_DIRS_DEP) - list(REMOVE_DUPLICATES CBLAS_LINKER_FLAGS) - else() - if(NOT CBLAS_FIND_QUIETLY) - message(STATUS "Looking for cblas : test of cblas_dscal with cblas and blas libraries fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(CBLAS_LIBRARIES) - - endif (CBLAS_STANDALONE OR NOT CBLAS_WORKS) + if (NOT CBLAS_STANDALONE) + # check if a cblas function exists in the BLAS lib + # this can be the case with libs such as MKL, ACML + include(CheckFunctionExists) + set(CMAKE_REQUIRED_LIBRARIES "${BLAS_LINKER_FLAGS};${BLAS_LIBRARIES}") + set(CMAKE_REQUIRED_FLAGS "${BLAS_COMPILER_FLAGS}") + unset(CBLAS_WORKS CACHE) + check_function_exists(cblas_dscal CBLAS_WORKS) + check_function_exists(cblas_zgemm3m CBLAS_ZGEMM3M_FOUND) + mark_as_advanced(CBLAS_WORKS) + set(CMAKE_REQUIRED_LIBRARIES) + + if(CBLAS_WORKS) + + # Check for faster complex GEMM routine + # (only C/Z, no S/D version) + if ( CBLAS_ZGEMM3M_FOUND ) + add_definitions(-DCBLAS_HAS_ZGEMM3M -DCBLAS_HAS_CGEMM3M) + endif() + + if(NOT CBLAS_FIND_QUIETLY) + message(STATUS "Looking for cblas: test with blas succeeds") + endif() + # test succeeds: CBLAS is in BLAS + set(CBLAS_LIBRARIES "${BLAS_LIBRARIES}") + if (BLAS_LIBRARY_DIRS) + set(CBLAS_LIBRARY_DIRS "${BLAS_LIBRARY_DIRS}") + endif() + if(BLAS_INCLUDE_DIRS) + set(CBLAS_INCLUDE_DIRS "${BLAS_INCLUDE_DIRS}") + endif() + if (BLAS_LINKER_FLAGS) + set(CBLAS_LINKER_FLAGS "${BLAS_LINKER_FLAGS}") + endif() + endif() + endif (NOT CBLAS_STANDALONE) -else(BLAS_FOUND) + if (CBLAS_STANDALONE OR NOT CBLAS_WORKS) - if (NOT CBLAS_FIND_QUIETLY) - message(STATUS "CBLAS requires BLAS but BLAS has not been found." - "Please look for BLAS first.") + if(NOT CBLAS_WORKS AND NOT CBLAS_FIND_QUIETLY) + message(STATUS "Looking for cblas : test with blas fails") + endif() + # test fails: try to find CBLAS lib exterior to BLAS + + # Try to find CBLAS lib + ####################### + + # Looking for include + # ------------------- + + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + set(ENV_CBLAS_DIR "$ENV{CBLAS_DIR}") + set(ENV_CBLAS_INCDIR "$ENV{CBLAS_INCDIR}") + if(ENV_CBLAS_INCDIR) + list(APPEND _inc_env "${ENV_CBLAS_INCDIR}") + elseif(ENV_CBLAS_DIR) + list(APPEND _inc_env "${ENV_CBLAS_DIR}") + list(APPEND _inc_env "${ENV_CBLAS_DIR}/include") + list(APPEND _inc_env "${ENV_CBLAS_DIR}/include/cblas") + else() + if(WIN32) + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) + + + # Try to find the cblas header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(CBLAS_INCDIR) + set(CBLAS_cblas.h_DIRS "CBLAS_cblas.h_DIRS-NOTFOUND") + find_path(CBLAS_cblas.h_DIRS + NAMES cblas.h + HINTS ${CBLAS_INCDIR}) + else() + if(CBLAS_DIR) + set(CBLAS_cblas.h_DIRS "CBLAS_cblas.h_DIRS-NOTFOUND") + find_path(CBLAS_cblas.h_DIRS + NAMES cblas.h + HINTS ${CBLAS_DIR} + PATH_SUFFIXES "include" "include/cblas") + else() + set(CBLAS_cblas.h_DIRS "CBLAS_cblas.h_DIRS-NOTFOUND") + find_path(CBLAS_cblas.h_DIRS + NAMES cblas.h + HINTS ${_inc_env} + PATH_SUFFIXES "cblas") + endif() + endif() + mark_as_advanced(CBLAS_cblas.h_DIRS) + + # If found, add path to cmake variable + # ------------------------------------ + if (CBLAS_cblas.h_DIRS) + set(CBLAS_INCLUDE_DIRS "${CBLAS_cblas.h_DIRS}") + else () + set(CBLAS_INCLUDE_DIRS "CBLAS_INCLUDE_DIRS-NOTFOUND") + if(NOT CBLAS_FIND_QUIETLY) + message(STATUS "Looking for cblas -- cblas.h not found") + endif() endif() -endif(BLAS_FOUND) -if (CBLAS_LIBRARIES) - list(GET CBLAS_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") - string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") - set(CBLAS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of CBLAS library" FORCE) + # Looking for lib + # --------------- + + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_CBLAS_LIBDIR "$ENV{CBLAS_LIBDIR}") + if(ENV_CBLAS_LIBDIR) + list(APPEND _lib_env "${ENV_CBLAS_LIBDIR}") + elseif(ENV_CBLAS_DIR) + list(APPEND _lib_env "${ENV_CBLAS_DIR}") + list(APPEND _lib_env "${ENV_CBLAS_DIR}/lib") else() - set(CBLAS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of CBLAS library" FORCE) + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() endif() + list(REMOVE_DUPLICATES _lib_env) + + # Try to find the cblas lib in the given paths + # ---------------------------------------------- + + # call cmake macro to find the lib path + if(CBLAS_LIBDIR) + set(CBLAS_cblas_LIBRARY "CBLAS_cblas_LIBRARY-NOTFOUND") + find_library(CBLAS_cblas_LIBRARY + NAMES cblas + HINTS ${CBLAS_LIBDIR}) + else() + if(CBLAS_DIR) + set(CBLAS_cblas_LIBRARY "CBLAS_cblas_LIBRARY-NOTFOUND") + find_library(CBLAS_cblas_LIBRARY + NAMES cblas + HINTS ${CBLAS_DIR} + PATH_SUFFIXES lib lib32 lib64) + else() + set(CBLAS_cblas_LIBRARY "CBLAS_cblas_LIBRARY-NOTFOUND") + find_library(CBLAS_cblas_LIBRARY + NAMES cblas + HINTS ${_lib_env}) + endif() + endif() + mark_as_advanced(CBLAS_cblas_LIBRARY) + + # If found, add path to cmake variable + # ------------------------------------ + if (CBLAS_cblas_LIBRARY) + get_filename_component(cblas_lib_path "${CBLAS_cblas_LIBRARY}" PATH) + # set cmake variables + set(CBLAS_LIBRARIES "${CBLAS_cblas_LIBRARY}") + set(CBLAS_LIBRARY_DIRS "${cblas_lib_path}") + else () + set(CBLAS_LIBRARIES "CBLAS_LIBRARIES-NOTFOUND") + set(CBLAS_LIBRARY_DIRS "CBLAS_LIBRARY_DIRS-NOTFOUND") + if (NOT CBLAS_FIND_QUIETLY) + message(STATUS "Looking for cblas -- lib cblas not found") + endif() + endif () + + # check a function to validate the find + if(CBLAS_LIBRARIES) + + set(REQUIRED_INCDIRS) + set(REQUIRED_LDFLAGS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # CBLAS + if (CBLAS_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS}") + endif() + if (CBLAS_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${CBLAS_LIBRARIES}") + # BLAS + if (BLAS_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${BLAS_INCLUDE_DIRS}") + endif() + if (BLAS_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${BLAS_LIBRARY_DIRS}") + endif() + list(APPEND REQUIRED_LIBS "${BLAS_LIBRARIES}") + if (BLAS_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") + endif() + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(CBLAS_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(cblas_dscal CBLAS_WORKS) + mark_as_advanced(CBLAS_WORKS) + + if(CBLAS_WORKS) + + # Check for faster complex GEMM routine + # (only C/Z, no S/D version) + check_function_exists(cblas_zgemm3m CBLAS_ZGEMM3M_FOUND) + if ( CBLAS_ZGEMM3M_FOUND ) + add_definitions(-DCBLAS_HAS_ZGEMM3M -DCBLAS_HAS_CGEMM3M) + endif() + + # save link with dependencies + set(CBLAS_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(CBLAS_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(CBLAS_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(CBLAS_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES CBLAS_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES CBLAS_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES CBLAS_LINKER_FLAGS) + else() + if(NOT CBLAS_FIND_QUIETLY) + message(STATUS "Looking for cblas : test of cblas_dscal with cblas and blas libraries fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(CBLAS_LIBRARIES) + + endif (CBLAS_STANDALONE OR NOT CBLAS_WORKS) + +else(BLAS_FOUND) + + if (NOT CBLAS_FIND_QUIETLY) + message(STATUS "CBLAS requires BLAS but BLAS has not been found." + "Please look for BLAS first.") + endif() + +endif(BLAS_FOUND) + +if (CBLAS_LIBRARIES) + list(GET CBLAS_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") + string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") + set(CBLAS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of CBLAS library" FORCE) + else() + set(CBLAS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of CBLAS library" FORCE) + endif() endif() +mark_as_advanced(CBLAS_DIR) +mark_as_advanced(CBLAS_DIR_FOUND) # check that CBLAS has been found # ------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CBLAS DEFAULT_MSG - CBLAS_LIBRARIES - CBLAS_WORKS) + CBLAS_LIBRARIES + CBLAS_WORKS) diff --git a/CMakeModules/morse/find/FindCHAMELEON.cmake b/CMakeModules/morse/find/FindCHAMELEON.cmake index 7e20d8223f4aa3f6a45eb74e4f1486134ff0af2e..9b581f5b908b590d612dbf5f235ae22e6977f4cc 100644 --- a/CMakeModules/morse/find/FindCHAMELEON.cmake +++ b/CMakeModules/morse/find/FindCHAMELEON.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -56,7 +56,7 @@ # Copyright 2012-2013 Emmanuel Agullo # Copyright 2012-2013 Mathieu Faverge # Copyright 2012 Cedric Castagnede -# Copyright 2013 Florent Pruvost +# Copyright 2013-2016 Florent Pruvost # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file MORSE-Copyright.txt for details. @@ -70,10 +70,10 @@ if (NOT CHAMELEON_FOUND) - set(CHAMELEON_DIR "" CACHE PATH "Installation directory of CHAMELEON library") - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "A cache variable, namely CHAMELEON_DIR, has been set to specify the install directory of CHAMELEON") - endif() + set(CHAMELEON_DIR "" CACHE PATH "Installation directory of CHAMELEON library") + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "A cache variable, namely CHAMELEON_DIR, has been set to specify the install directory of CHAMELEON") + endif() endif() # Try to find CHAMELEON dependencies if specified as COMPONENTS during the call @@ -85,34 +85,34 @@ set(CHAMELEON_LOOK_FOR_MPI OFF) set(CHAMELEON_LOOK_FOR_FXT OFF) if( CHAMELEON_FIND_COMPONENTS ) - foreach( component ${CHAMELEON_FIND_COMPONENTS} ) - if (${component} STREQUAL "STARPU") - # means we look for Chameleon with StarPU - set(CHAMELEON_LOOK_FOR_STARPU ON) - set(CHAMELEON_LOOK_FOR_QUARK OFF) - endif() - if (${component} STREQUAL "QUARK") - # means we look for Chameleon with QUARK - set(CHAMELEON_LOOK_FOR_QUARK ON) - set(CHAMELEON_LOOK_FOR_STARPU OFF) - endif() - if (${component} STREQUAL "CUDA") - # means we look for Chameleon with CUDA - set(CHAMELEON_LOOK_FOR_CUDA ON) - endif() - if (${component} STREQUAL "MAGMA") - # means we look for Chameleon with MAGMA - set(CHAMELEON_LOOK_FOR_MAGMA ON) - endif() - if (${component} STREQUAL "MPI") - # means we look for Chameleon with MPI - set(CHAMELEON_LOOK_FOR_MPI ON) - endif() - if (${component} STREQUAL "FXT") - # means we look for Chameleon with FXT - set(CHAMELEON_LOOK_FOR_FXT ON) - endif() - endforeach() + foreach( component ${CHAMELEON_FIND_COMPONENTS} ) + if (${component} STREQUAL "STARPU") + # means we look for Chameleon with StarPU + set(CHAMELEON_LOOK_FOR_STARPU ON) + set(CHAMELEON_LOOK_FOR_QUARK OFF) + endif() + if (${component} STREQUAL "QUARK") + # means we look for Chameleon with QUARK + set(CHAMELEON_LOOK_FOR_QUARK ON) + set(CHAMELEON_LOOK_FOR_STARPU OFF) + endif() + if (${component} STREQUAL "CUDA") + # means we look for Chameleon with CUDA + set(CHAMELEON_LOOK_FOR_CUDA ON) + endif() + if (${component} STREQUAL "MAGMA") + # means we look for Chameleon with MAGMA + set(CHAMELEON_LOOK_FOR_MAGMA ON) + endif() + if (${component} STREQUAL "MPI") + # means we look for Chameleon with MPI + set(CHAMELEON_LOOK_FOR_MPI ON) + endif() + if (${component} STREQUAL "FXT") + # means we look for Chameleon with FXT + set(CHAMELEON_LOOK_FOR_FXT ON) + endif() + endforeach() endif() set(ENV_CHAMELEON_DIR "$ENV{CHAMELEON_DIR}") @@ -120,7 +120,7 @@ set(ENV_CHAMELEON_INCDIR "$ENV{CHAMELEON_INCDIR}") set(ENV_CHAMELEON_LIBDIR "$ENV{CHAMELEON_LIBDIR}") set(CHAMELEON_GIVEN_BY_USER "FALSE") if ( CHAMELEON_DIR OR ( CHAMELEON_INCDIR AND CHAMELEON_LIBDIR) OR ENV_CHAMELEON_DIR OR (ENV_CHAMELEON_INCDIR AND ENV_CHAMELEON_LIBDIR) ) - set(CHAMELEON_GIVEN_BY_USER "TRUE") + set(CHAMELEON_GIVEN_BY_USER "TRUE") endif() # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) @@ -129,670 +129,672 @@ include(FindPkgConfig) find_package(PkgConfig QUIET) if(PKG_CONFIG_EXECUTABLE AND NOT CHAMELEON_GIVEN_BY_USER) - pkg_search_module(CHAMELEON chameleon) - if (NOT CHAMELEON_FIND_QUIETLY) - if (CHAMELEON_FOUND AND CHAMELEON_LIBRARIES) - message(STATUS "Looking for CHAMELEON - found using PkgConfig") - #if(NOT CHAMELEON_INCLUDE_DIRS) - # message("${Magenta}CHAMELEON_INCLUDE_DIRS is empty using PkgConfig." - # "Perhaps the path to chameleon headers is already present in your" - # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") - #endif() - else() - message("${Magenta}Looking for CHAMELEON - not found using PkgConfig." - "Perhaps you should add the directory containing chameleon.pc" - "to the PKG_CONFIG_PATH environment variable.${ColourReset}") - endif() - endif() - - if (CHAMELEON_FIND_VERSION_EXACT) - if( NOT (CHAMELEON_FIND_VERSION_MAJOR STREQUAL CHAMELEON_VERSION_MAJOR) OR - NOT (CHAMELEON_FIND_VERSION_MINOR STREQUAL CHAMELEON_VERSION_MINOR) ) - if(NOT CHAMELEON_FIND_QUIETLY) - message(FATAL_ERROR - "CHAMELEON version found is ${CHAMELEON_VERSION_STRING}" - "when required is ${CHAMELEON_FIND_VERSION}") - endif() - endif() + pkg_search_module(CHAMELEON chameleon) + if (NOT CHAMELEON_FIND_QUIETLY) + if (CHAMELEON_FOUND AND CHAMELEON_LIBRARIES) + message(STATUS "Looking for CHAMELEON - found using PkgConfig") + #if(NOT CHAMELEON_INCLUDE_DIRS) + # message("${Magenta}CHAMELEON_INCLUDE_DIRS is empty using PkgConfig." + # "Perhaps the path to chameleon headers is already present in your" + # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") + #endif() else() - # if the version found is older than the required then error - if( (CHAMELEON_FIND_VERSION_MAJOR STRGREATER CHAMELEON_VERSION_MAJOR) OR - (CHAMELEON_FIND_VERSION_MINOR STRGREATER CHAMELEON_VERSION_MINOR) ) - if(NOT CHAMELEON_FIND_QUIETLY) - message(FATAL_ERROR - "CHAMELEON version found is ${CHAMELEON_VERSION_STRING}" - "when required is ${CHAMELEON_FIND_VERSION} or newer") - endif() - endif() + message(STATUS "${Magenta}Looking for CHAMELEON - not found using PkgConfig." + "\n Perhaps you should add the directory containing chameleon.pc" + "\n to the PKG_CONFIG_PATH environment variable.${ColourReset}") endif() + endif() + + if (CHAMELEON_FIND_VERSION_EXACT) + if( NOT (CHAMELEON_FIND_VERSION_MAJOR STREQUAL CHAMELEON_VERSION_MAJOR) OR + NOT (CHAMELEON_FIND_VERSION_MINOR STREQUAL CHAMELEON_VERSION_MINOR) ) + if(NOT CHAMELEON_FIND_QUIETLY) + message(FATAL_ERROR + "CHAMELEON version found is ${CHAMELEON_VERSION_STRING}" + "when required is ${CHAMELEON_FIND_VERSION}") + endif() + endif() + else() + # if the version found is older than the required then error + if( (CHAMELEON_FIND_VERSION_MAJOR STRGREATER CHAMELEON_VERSION_MAJOR) OR + (CHAMELEON_FIND_VERSION_MINOR STRGREATER CHAMELEON_VERSION_MINOR) ) + if(NOT CHAMELEON_FIND_QUIETLY) + message(FATAL_ERROR + "CHAMELEON version found is ${CHAMELEON_VERSION_STRING}" + "when required is ${CHAMELEON_FIND_VERSION} or newer") + endif() + endif() + endif() - set(CHAMELEON_INCLUDE_DIRS_DEP "${CHAMELEON_INCLUDE_DIRS}") - set(CHAMELEON_LIBRARY_DIRS_DEP "${CHAMELEON_LIBRARY_DIRS}") - set(CHAMELEON_LIBRARIES_DEP "${CHAMELEON_LIBRARIES}") + set(CHAMELEON_INCLUDE_DIRS_DEP "${CHAMELEON_INCLUDE_DIRS}") + set(CHAMELEON_LIBRARY_DIRS_DEP "${CHAMELEON_LIBRARY_DIRS}") + set(CHAMELEON_LIBRARIES_DEP "${CHAMELEON_LIBRARIES}") endif(PKG_CONFIG_EXECUTABLE AND NOT CHAMELEON_GIVEN_BY_USER) if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT CHAMELEON_FOUND) OR (CHAMELEON_GIVEN_BY_USER) ) - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - PkgConfig not used") + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - PkgConfig not used") + endif() + + # Dependencies detection + # ---------------------- + + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - Try to detect pthread") + endif() + if (CHAMELEON_FIND_REQUIRED) + find_package(Threads REQUIRED) + else() + find_package(Threads) + endif() + set(CHAMELEON_EXTRA_LIBRARIES "") + if( THREADS_FOUND ) + list(APPEND CHAMELEON_EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + endif () + + # Add math library to the list of extra + # it normally exists on all common systems provided with a C compiler + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - Try to detect libm") + endif() + set(CHAMELEON_M_LIBRARIES "") + if(UNIX OR WIN32) + find_library( + CHAMELEON_M_m_LIBRARY + NAMES m + ) + mark_as_advanced(CHAMELEON_M_m_LIBRARY) + if (CHAMELEON_M_m_LIBRARY) + list(APPEND CHAMELEON_M_LIBRARIES "${CHAMELEON_M_m_LIBRARY}") + list(APPEND CHAMELEON_EXTRA_LIBRARIES "${CHAMELEON_M_m_LIBRARY}") + else() + if (CHAMELEON_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find libm on your system." + "Are you sure to a have a C compiler installed?") + endif() endif() - - # Dependencies detection - # ---------------------- - - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - Try to detect pthread") + endif() + + # Try to find librt (libposix4 - POSIX.1b Realtime Extensions library) + # on Unix systems except Apple ones because it does not exist on it + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - Try to detect librt") + endif() + set(CHAMELEON_RT_LIBRARIES "") + if(UNIX AND NOT APPLE) + find_library( + CHAMELEON_RT_rt_LIBRARY + NAMES rt + ) + mark_as_advanced(CHAMELEON_RT_rt_LIBRARY) + if (CHAMELEON_RT_rt_LIBRARY) + list(APPEND CHAMELEON_RT_LIBRARIES "${CHAMELEON_RT_rt_LIBRARY}") + list(APPEND CHAMELEON_EXTRA_LIBRARIES "${CHAMELEON_RT_rt_LIBRARY}") + else() + if (CHAMELEON_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find librt on your system") + endif() endif() - if (CHAMELEON_FIND_REQUIRED) - find_package(Threads REQUIRED) + endif() + + # CHAMELEON depends on CBLAS + #--------------------------- + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - Try to detect CBLAS (depends on BLAS)") + endif() + if (CHAMELEON_FIND_REQUIRED) + find_package(CBLAS REQUIRED) + else() + find_package(CBLAS) + endif() + + # CHAMELEON depends on LAPACKE + #----------------------------- + + # standalone version of lapacke seems useless for now + # let the comment in case we meet some problems of non existing lapacke + # functions in lapack library such as mkl, acml, ... + #set(LAPACKE_STANDALONE TRUE) + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - Try to detect LAPACKE (depends on LAPACK)") + endif() + if (CHAMELEON_FIND_REQUIRED) + find_package(LAPACKE REQUIRED) + else() + find_package(LAPACKE) + endif() + + # CHAMELEON depends on TMG + #------------------------- + if (NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for CHAMELEON - Try to detect TMG (depends on LAPACK)") + endif() + if (CHAMELEON_FIND_REQUIRED) + find_package(TMG REQUIRED) + else() + find_package(TMG) + endif() + + # CHAMELEON may depend on CUDA/CUBLAS + #------------------------------------ + if (NOT CUDA_FOUND AND CHAMELEON_LOOK_FOR_CUDA) + if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_CUDA) + find_package(CUDA REQUIRED) else() - find_package(Threads) - endif() - set(CHAMELEON_EXTRA_LIBRARIES "") - if( THREADS_FOUND ) - list(APPEND CHAMELEON_EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) - endif () - - # Add math library to the list of extra - # it normally exists on all common systems provided with a C compiler - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - Try to detect libm") - endif() - set(CHAMELEON_M_LIBRARIES "") - if(UNIX OR WIN32) - find_library( - CHAMELEON_M_m_LIBRARY - NAMES m - ) - mark_as_advanced(CHAMELEON_M_m_LIBRARY) - if (CHAMELEON_M_m_LIBRARY) - list(APPEND CHAMELEON_M_LIBRARIES "${CHAMELEON_M_m_LIBRARY}") - list(APPEND CHAMELEON_EXTRA_LIBRARIES "${CHAMELEON_M_m_LIBRARY}") - else() - if (CHAMELEON_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find libm on your system." - "Are you sure to a have a C compiler installed?") - endif() - endif() - endif() - - # Try to find librt (libposix4 - POSIX.1b Realtime Extensions library) - # on Unix systems except Apple ones because it does not exist on it - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - Try to detect librt") - endif() - set(CHAMELEON_RT_LIBRARIES "") - if(UNIX AND NOT APPLE) - find_library( - CHAMELEON_RT_rt_LIBRARY - NAMES rt - ) - mark_as_advanced(CHAMELEON_RT_rt_LIBRARY) - if (CHAMELEON_RT_rt_LIBRARY) - list(APPEND CHAMELEON_RT_LIBRARIES "${CHAMELEON_RT_rt_LIBRARY}") - list(APPEND CHAMELEON_EXTRA_LIBRARIES "${CHAMELEON_RT_rt_LIBRARY}") - else() - if (CHAMELEON_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find librt on your system") - endif() - endif() - endif() - - # CHAMELEON depends on CBLAS - #--------------------------- - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - Try to detect CBLAS (depends on BLAS)") - endif() - if (CHAMELEON_FIND_REQUIRED) - find_package(CBLAS REQUIRED COMPONENTS BLASEXT) + find_package(CUDA) + endif() + if (CUDA_FOUND) + mark_as_advanced(CUDA_BUILD_CUBIN) + mark_as_advanced(CUDA_BUILD_EMULATION) + mark_as_advanced(CUDA_SDK_ROOT_DIR) + mark_as_advanced(CUDA_TOOLKIT_ROOT_DIR) + mark_as_advanced(CUDA_VERBOSE_BUILD) + endif() + endif() + + # CHAMELEON may depend on MAGMA gpu kernels + # call our cmake module to test (in cmake_modules) + # change this call position if not appropriated + #------------------------------------------------- + if( CUDA_FOUND AND CHAMELEON_LOOK_FOR_MAGMA ) + set(CHAMELEON_MAGMA_VERSION "1.4" CACHE STRING "oldest MAGMA version desired") + if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_MAGMA) + find_package(MAGMA ${CHAMELEON_MAGMA_VERSION} REQUIRED) else() - find_package(CBLAS COMPONENTS BLASEXT) + find_package(MAGMA ${CHAMELEON_MAGMA_VERSION}) endif() + endif() - # CHAMELEON depends on LAPACKE - #----------------------------- + # CHAMELEON depends on MPI + #------------------------- + if( NOT MPI_FOUND AND CHAMELEON_LOOK_FOR_MPI ) - # standalone version of lapacke seems useless for now - # let the comment in case we meet some problems of non existing lapacke - # functions in lapack library such as mkl, acml, ... - #set(LAPACKE_STANDALONE TRUE) - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - Try to detect LAPACKE (depends on LAPACK)") + # allows to use an external mpi compilation by setting compilers with + # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90 + # at cmake configure + if(NOT MPI_C_COMPILER) + set(MPI_C_COMPILER mpicc) endif() - if (CHAMELEON_FIND_REQUIRED) - find_package(LAPACKE REQUIRED COMPONENTS LAPACKEXT) + if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_MPI) + find_package(MPI REQUIRED) else() - find_package(LAPACKE COMPONENTS LAPACKEXT) + find_package(MPI) endif() + if (MPI_FOUND) + mark_as_advanced(MPI_LIBRARY) + mark_as_advanced(MPI_EXTRA_LIBRARY) + endif() + + endif() + + if( NOT STARPU_FOUND AND CHAMELEON_LOOK_FOR_STARPU ) + + set(CHAMELEON_STARPU_VERSION "1.1" CACHE STRING "oldest STARPU version desired") - # CHAMELEON depends on TMG - #------------------------- - if (NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for CHAMELEON - Try to detect TMG (depends on LAPACK)") + # create list of components in order to make a single call to find_package(starpu...) + # we explicitly need a StarPU version built with hwloc + set(STARPU_COMPONENT_LIST "HWLOC") + + # StarPU may depend on MPI + # allows to use an external mpi compilation by setting compilers with + # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90 + # at cmake configure + if (CHAMELEON_LOOK_FOR_MPI) + if(NOT MPI_C_COMPILER) + set(MPI_C_COMPILER mpicc) + endif() + list(APPEND STARPU_COMPONENT_LIST "MPI") + endif() + if (CHAMELEON_LOOK_FOR_CUDA) + list(APPEND STARPU_COMPONENT_LIST "CUDA") endif() - if (CHAMELEON_FIND_REQUIRED) - find_package(TMG REQUIRED) + if (CHAMELEON_LOOK_FOR_FXT) + list(APPEND STARPU_COMPONENT_LIST "FXT") + endif() + if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_STARPU) + find_package(STARPU ${CHAMELEON_STARPU_VERSION} REQUIRED + COMPONENTS ${STARPU_COMPONENT_LIST}) else() - find_package(TMG) - endif() - - # CHAMELEON may depend on CUDA/CUBLAS - #------------------------------------ - if (NOT CUDA_FOUND AND CHAMELEON_LOOK_FOR_CUDA) - if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_CUDA) - find_package(CUDA REQUIRED) - else() - find_package(CUDA) - endif() - if (CUDA_FOUND) - mark_as_advanced(CUDA_BUILD_CUBIN) - mark_as_advanced(CUDA_BUILD_EMULATION) - mark_as_advanced(CUDA_SDK_ROOT_DIR) - mark_as_advanced(CUDA_TOOLKIT_ROOT_DIR) - mark_as_advanced(CUDA_VERBOSE_BUILD) - endif() - endif() - - # CHAMELEON may depend on MAGMA gpu kernels - # call our cmake module to test (in cmake_modules) - # change this call position if not appropriated - #------------------------------------------------- - if( CUDA_FOUND AND CHAMELEON_LOOK_FOR_MAGMA ) - set(CHAMELEON_MAGMA_VERSION "1.4" CACHE STRING "oldest MAGMA version desired") - if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_MAGMA) - find_package(MAGMA ${CHAMELEON_MAGMA_VERSION} REQUIRED) - else() - find_package(MAGMA ${CHAMELEON_MAGMA_VERSION}) - endif() - endif() - - # CHAMELEON depends on MPI - #------------------------- - if( NOT MPI_FOUND AND CHAMELEON_LOOK_FOR_MPI ) - - # allows to use an external mpi compilation by setting compilers with - # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90 - # at cmake configure - if(NOT MPI_C_COMPILER) - set(MPI_C_COMPILER mpicc) - endif() - if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_MPI) - find_package(MPI REQUIRED) - else() - find_package(MPI) - endif() - if (MPI_FOUND) - mark_as_advanced(MPI_LIBRARY) - mark_as_advanced(MPI_EXTRA_LIBRARY) - endif() - - endif() - - if( NOT STARPU_FOUND AND CHAMELEON_LOOK_FOR_STARPU ) - - set(CHAMELEON_STARPU_VERSION "1.1" CACHE STRING "oldest STARPU version desired") - - # create list of components in order to make a single call to find_package(starpu...) - # we explicitly need a StarPU version built with hwloc - set(STARPU_COMPONENT_LIST "HWLOC") - - # StarPU may depend on MPI - # allows to use an external mpi compilation by setting compilers with - # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90 - # at cmake configure - if (CHAMELEON_LOOK_FOR_MPI) - if(NOT MPI_C_COMPILER) - set(MPI_C_COMPILER mpicc) - endif() - list(APPEND STARPU_COMPONENT_LIST "MPI") - endif() - if (CHAMELEON_LOOK_FOR_CUDA) - list(APPEND STARPU_COMPONENT_LIST "CUDA") - endif() - if (CHAMELEON_LOOK_FOR_FXT) - list(APPEND STARPU_COMPONENT_LIST "FXT") - endif() - if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_STARPU) - find_package(STARPU ${CHAMELEON_STARPU_VERSION} REQUIRED - COMPONENTS ${STARPU_COMPONENT_LIST}) - else() - find_package(STARPU ${CHAMELEON_STARPU_VERSION} - COMPONENTS ${STARPU_COMPONENT_LIST}) - endif() - - endif() - - if( NOT QUARK_FOUND AND CHAMELEON_LOOK_FOR_QUARK ) - - # try to find quark runtime - if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_QUARK) - find_package(QUARK REQUIRED COMPONENTS HWLOC) - else() - find_package(QUARK COMPONENTS HWLOC) - endif() - - endif() - - # Looking for include - # ------------------- - - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - set(ENV_CHAMELEON_DIR "$ENV{CHAMELEON_DIR}") - set(ENV_CHAMELEON_INCDIR "$ENV{CHAMELEON_INCDIR}") - if(ENV_CHAMELEON_INCDIR) - list(APPEND _inc_env "${ENV_CHAMELEON_INCDIR}") - elseif(ENV_CHAMELEON_DIR) - list(APPEND _inc_env "${ENV_CHAMELEON_DIR}") - list(APPEND _inc_env "${ENV_CHAMELEON_DIR}/include") - list(APPEND _inc_env "${ENV_CHAMELEON_DIR}/include/chameleon") + find_package(STARPU ${CHAMELEON_STARPU_VERSION} + COMPONENTS ${STARPU_COMPONENT_LIST}) + endif() + + endif() + + if( NOT QUARK_FOUND AND CHAMELEON_LOOK_FOR_QUARK ) + + # try to find quark runtime + if (CHAMELEON_FIND_REQUIRED AND CHAMELEON_FIND_REQUIRED_QUARK) + find_package(QUARK REQUIRED COMPONENTS HWLOC) else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() - endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) - - - # Try to find the chameleon header in the given paths - # --------------------------------------------------- - # call cmake macro to find the header path - if(CHAMELEON_INCDIR) - set(CHAMELEON_morse.h_DIRS "CHAMELEON_morse.h_DIRS-NOTFOUND") - find_path(CHAMELEON_morse.h_DIRS - NAMES morse.h - HINTS ${CHAMELEON_INCDIR}) + find_package(QUARK COMPONENTS HWLOC) + endif() + + endif() + + # Looking for include + # ------------------- + + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + set(ENV_CHAMELEON_DIR "$ENV{CHAMELEON_DIR}") + set(ENV_CHAMELEON_INCDIR "$ENV{CHAMELEON_INCDIR}") + if(ENV_CHAMELEON_INCDIR) + list(APPEND _inc_env "${ENV_CHAMELEON_INCDIR}") + elseif(ENV_CHAMELEON_DIR) + list(APPEND _inc_env "${ENV_CHAMELEON_DIR}") + list(APPEND _inc_env "${ENV_CHAMELEON_DIR}/include") + list(APPEND _inc_env "${ENV_CHAMELEON_DIR}/include/chameleon") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") else() - if(CHAMELEON_DIR) - set(CHAMELEON_morse.h_DIRS "CHAMELEON_morse.h_DIRS-NOTFOUND") - find_path(CHAMELEON_morse.h_DIRS - NAMES morse.h - HINTS ${CHAMELEON_DIR} - PATH_SUFFIXES "include" "include/chameleon") - else() - set(CHAMELEON_morse.h_DIRS "CHAMELEON_morse.h_DIRS-NOTFOUND") - find_path(CHAMELEON_morse.h_DIRS - NAMES morse.h - HINTS ${_inc_env} - PATH_SUFFIXES "chameleon") - endif() - endif() - mark_as_advanced(CHAMELEON_morse.h_DIRS) - - # If found, add path to cmake variable - # ------------------------------------ - if (CHAMELEON_morse.h_DIRS) - set(CHAMELEON_INCLUDE_DIRS "${CHAMELEON_morse.h_DIRS}") - else () - set(CHAMELEON_INCLUDE_DIRS "CHAMELEON_INCLUDE_DIRS-NOTFOUND") - if(NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for chameleon -- morse.h not found") - endif() - endif() - - - # Looking for lib - # --------------- - - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - set(ENV_CHAMELEON_LIBDIR "$ENV{CHAMELEON_LIBDIR}") - if(ENV_CHAMELEON_LIBDIR) - list(APPEND _lib_env "${ENV_CHAMELEON_LIBDIR}") - elseif(ENV_CHAMELEON_DIR) - list(APPEND _lib_env "${ENV_CHAMELEON_DIR}") - list(APPEND _lib_env "${ENV_CHAMELEON_DIR}/lib") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) + + + # Try to find the chameleon header in the given paths + # --------------------------------------------------- + # call cmake macro to find the header path + if(CHAMELEON_INCDIR) + set(CHAMELEON_morse.h_DIRS "CHAMELEON_morse.h_DIRS-NOTFOUND") + find_path(CHAMELEON_morse.h_DIRS + NAMES morse.h + HINTS ${CHAMELEON_INCDIR}) + else() + if(CHAMELEON_DIR) + set(CHAMELEON_morse.h_DIRS "CHAMELEON_morse.h_DIRS-NOTFOUND") + find_path(CHAMELEON_morse.h_DIRS + NAMES morse.h + HINTS ${CHAMELEON_DIR} + PATH_SUFFIXES "include" "include/chameleon") else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() - endif() - list(REMOVE_DUPLICATES _lib_env) - - # Try to find the chameleon lib in the given paths - # ------------------------------------------------ - - # create list of libs to find - set(CHAMELEON_libs_to_find "chameleon") - if (STARPU_FOUND) - list(APPEND CHAMELEON_libs_to_find "chameleon_starpu") - elseif (QUARK_FOUND) - list(APPEND CHAMELEON_libs_to_find "chameleon_quark") - endif() - list(APPEND CHAMELEON_libs_to_find "coreblas") - - # call cmake macro to find the lib path - if(CHAMELEON_LIBDIR) - foreach(chameleon_lib ${CHAMELEON_libs_to_find}) - set(CHAMELEON_${chameleon_lib}_LIBRARY "CHAMELEON_${chameleon_lib}_LIBRARY-NOTFOUND") - find_library(CHAMELEON_${chameleon_lib}_LIBRARY - NAMES ${chameleon_lib} - HINTS ${CHAMELEON_LIBDIR}) - endforeach() + set(CHAMELEON_morse.h_DIRS "CHAMELEON_morse.h_DIRS-NOTFOUND") + find_path(CHAMELEON_morse.h_DIRS + NAMES morse.h + HINTS ${_inc_env} + PATH_SUFFIXES "chameleon") + endif() + endif() + mark_as_advanced(CHAMELEON_morse.h_DIRS) + + # If found, add path to cmake variable + # ------------------------------------ + if (CHAMELEON_morse.h_DIRS) + set(CHAMELEON_INCLUDE_DIRS "${CHAMELEON_morse.h_DIRS}") + else () + set(CHAMELEON_INCLUDE_DIRS "CHAMELEON_INCLUDE_DIRS-NOTFOUND") + if(NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for chameleon -- morse.h not found") + endif() + endif() + + + # Looking for lib + # --------------- + + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_CHAMELEON_LIBDIR "$ENV{CHAMELEON_LIBDIR}") + if(ENV_CHAMELEON_LIBDIR) + list(APPEND _lib_env "${ENV_CHAMELEON_LIBDIR}") + elseif(ENV_CHAMELEON_DIR) + list(APPEND _lib_env "${ENV_CHAMELEON_DIR}") + list(APPEND _lib_env "${ENV_CHAMELEON_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") else() - if(CHAMELEON_DIR) - foreach(chameleon_lib ${CHAMELEON_libs_to_find}) - set(CHAMELEON_${chameleon_lib}_LIBRARY "CHAMELEON_${chameleon_lib}_LIBRARY-NOTFOUND") - find_library(CHAMELEON_${chameleon_lib}_LIBRARY - NAMES ${chameleon_lib} - HINTS ${CHAMELEON_DIR} - PATH_SUFFIXES lib lib32 lib64) - endforeach() - else() - foreach(chameleon_lib ${CHAMELEON_libs_to_find}) - set(CHAMELEON_${chameleon_lib}_LIBRARY "CHAMELEON_${chameleon_lib}_LIBRARY-NOTFOUND") - find_library(CHAMELEON_${chameleon_lib}_LIBRARY - NAMES ${chameleon_lib} - HINTS ${_lib_env}) - endforeach() - endif() - endif() - - # If found, add path to cmake variable - # ------------------------------------ + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() + endif() + list(REMOVE_DUPLICATES _lib_env) + + # Try to find the chameleon lib in the given paths + # ------------------------------------------------ + + # create list of libs to find + set(CHAMELEON_libs_to_find "chameleon") + if (STARPU_FOUND) + list(APPEND CHAMELEON_libs_to_find "chameleon_starpu") + elseif (QUARK_FOUND) + list(APPEND CHAMELEON_libs_to_find "chameleon_quark") + endif() + list(APPEND CHAMELEON_libs_to_find "coreblas") + + # call cmake macro to find the lib path + if(CHAMELEON_LIBDIR) foreach(chameleon_lib ${CHAMELEON_libs_to_find}) + set(CHAMELEON_${chameleon_lib}_LIBRARY "CHAMELEON_${chameleon_lib}_LIBRARY-NOTFOUND") + find_library(CHAMELEON_${chameleon_lib}_LIBRARY + NAMES ${chameleon_lib} + HINTS ${CHAMELEON_LIBDIR}) + endforeach() + else() + if(CHAMELEON_DIR) + foreach(chameleon_lib ${CHAMELEON_libs_to_find}) + set(CHAMELEON_${chameleon_lib}_LIBRARY "CHAMELEON_${chameleon_lib}_LIBRARY-NOTFOUND") + find_library(CHAMELEON_${chameleon_lib}_LIBRARY + NAMES ${chameleon_lib} + HINTS ${CHAMELEON_DIR} + PATH_SUFFIXES lib lib32 lib64) + endforeach() + else() + foreach(chameleon_lib ${CHAMELEON_libs_to_find}) + set(CHAMELEON_${chameleon_lib}_LIBRARY "CHAMELEON_${chameleon_lib}_LIBRARY-NOTFOUND") + find_library(CHAMELEON_${chameleon_lib}_LIBRARY + NAMES ${chameleon_lib} + HINTS ${_lib_env}) + endforeach() + endif() + endif() - get_filename_component(${chameleon_lib}_lib_path ${CHAMELEON_${chameleon_lib}_LIBRARY} PATH) - # set cmake variables (respects naming convention) - if (CHAMELEON_LIBRARIES) - list(APPEND CHAMELEON_LIBRARIES "${CHAMELEON_${chameleon_lib}_LIBRARY}") - else() - set(CHAMELEON_LIBRARIES "${CHAMELEON_${chameleon_lib}_LIBRARY}") - endif() - if (CHAMELEON_LIBRARY_DIRS) - list(APPEND CHAMELEON_LIBRARY_DIRS "${${chameleon_lib}_lib_path}") - else() - set(CHAMELEON_LIBRARY_DIRS "${${chameleon_lib}_lib_path}") - endif() - mark_as_advanced(CHAMELEON_${chameleon_lib}_LIBRARY) - - endforeach(chameleon_lib ${CHAMELEON_libs_to_find}) - - # check a function to validate the find - if(CHAMELEON_LIBRARIES) - - set(REQUIRED_LDFLAGS) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) - - # CHAMELEON - if (CHAMELEON_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${CHAMELEON_INCLUDE_DIRS}") - endif() - foreach(libdir ${CHAMELEON_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - set(REQUIRED_LIBS "${CHAMELEON_LIBRARIES}") - # STARPU - if (STARPU_FOUND AND CHAMELEON_LOOK_FOR_STARPU) - if (STARPU_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS_DEP}") - elseif (STARPU_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS}") - endif() - if(STARPU_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS_DEP}") - elseif(STARPU_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS}") - endif() - if (STARPU_LIBRARIES_DEP) - list(APPEND REQUIRED_LIBS "${STARPU_LIBRARIES_DEP}") - elseif (STARPU_LIBRARIES) - foreach(lib ${STARPU_LIBRARIES}) - if (EXISTS ${lib} OR ${lib} MATCHES "^-") - list(APPEND REQUIRED_LIBS "${lib}") - else() - list(APPEND REQUIRED_LIBS "-l${lib}") - endif() - endforeach() - endif() - endif() - # QUARK - if (QUARK_FOUND AND CHAMELEON_LOOK_FOR_QUARK) - if (QUARK_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${QUARK_INCLUDE_DIRS_DEP}") - elseif(QUARK_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${QUARK_INCLUDE_DIRS}") - endif() - if(QUARK_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${QUARK_LIBRARY_DIRS_DEP}") - elseif(QUARK_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${QUARK_LIBRARY_DIRS}") - endif() - if (QUARK_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBS "${QUARK_LIBRARIES_DEP}") - elseif (QUARK_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBS "${QUARK_LIBRARIES}") - endif() - endif() - # CUDA - if (CUDA_FOUND AND CHAMELEON_LOOK_FOR_CUDA) - if (CUDA_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${CUDA_INCLUDE_DIRS}") - endif() - foreach(libdir ${CUDA_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - list(APPEND REQUIRED_LIBS "${CUDA_CUBLAS_LIBRARIES};${CUDA_LIBRARIES}") - endif() - # MAGMA - if (MAGMA_FOUND AND CHAMELEON_LOOK_FOR_MAGMA) - if (MAGMA_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${MAGMA_INCLUDE_DIRS_DEP}") - elseif(MAGMA_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${MAGMA_INCLUDE_DIRS}") - endif() - if (MAGMA_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${MAGMA_LIBRARY_DIRS_DEP}") - elseif(MAGMA_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${MAGMA_LIBRARY_DIRS}") - endif() - if (MAGMA_LIBRARIES_DEP) - list(APPEND REQUIRED_LIBS "${MAGMA_LIBRARIES_DEP}") - elseif(MAGMA_LIBRARIES) - foreach(lib ${MAGMA_LIBRARIES}) - if (EXISTS ${lib} OR ${lib} MATCHES "^-") - list(APPEND REQUIRED_LIBS "${lib}") - else() - list(APPEND REQUIRED_LIBS "-l${lib}") - endif() - endforeach() - endif() - endif() - # MPI - if (MPI_FOUND AND CHAMELEON_LOOK_FOR_MPI) - if (MPI_C_INCLUDE_PATH) - list(APPEND REQUIRED_INCDIRS "${MPI_C_INCLUDE_PATH}") - endif() - if (MPI_C_LINK_FLAGS) - if (${MPI_C_LINK_FLAGS} MATCHES " -") - string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS}) - endif() - list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}") - endif() - list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}") - endif() - # HWLOC - if (HWLOC_FOUND) - if (HWLOC_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}") - endif() - foreach(libdir ${HWLOC_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - foreach(lib ${HWLOC_LIBRARIES}) - if (EXISTS ${lib} OR ${lib} MATCHES "^-") - list(APPEND REQUIRED_LIBS "${lib}") - else() - list(APPEND REQUIRED_LIBS "-l${lib}") - endif() - endforeach() - endif() - # TMG - if (TMG_FOUND) - if (TMG_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${TMG_INCLUDE_DIRS_DEP}") - elseif (TMG_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${TMG_INCLUDE_DIRS}") - endif() - if(TMG_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${TMG_LIBRARY_DIRS_DEP}") - elseif(TMG_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${TMG_LIBRARY_DIRS}") - endif() - if (TMG_LIBRARIES_DEP) - list(APPEND REQUIRED_LIBS "${TMG_LIBRARIES_DEP}") - elseif(TMG_LIBRARIES) - list(APPEND REQUIRED_LIBS "${TMG_LIBRARIES}") - endif() - if (TMG_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${TMG_LINKER_FLAGS}") - endif() - endif() - # LAPACKE - if (LAPACKE_FOUND) - if (LAPACKE_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${LAPACKE_INCLUDE_DIRS_DEP}") - elseif (LAPACKE_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${LAPACKE_INCLUDE_DIRS}") - endif() - if(LAPACKE_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${LAPACKE_LIBRARY_DIRS_DEP}") - elseif(LAPACKE_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${LAPACKE_LIBRARY_DIRS}") - endif() - if (LAPACKE_LIBRARIES_DEP) - list(APPEND REQUIRED_LIBS "${LAPACKE_LIBRARIES_DEP}") - elseif(LAPACKE_LIBRARIES) - list(APPEND REQUIRED_LIBS "${LAPACKE_LIBRARIES}") - endif() - if (LAPACK_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") - endif() - endif() - # CBLAS - if (CBLAS_FOUND) - if (CBLAS_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS_DEP}") - elseif (CBLAS_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS}") - endif() - if(CBLAS_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS_DEP}") - elseif(CBLAS_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS}") - endif() - if (CBLAS_LIBRARIES_DEP) - list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES_DEP}") - elseif(CBLAS_LIBRARIES) - list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES}") - endif() - if (BLAS_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") - endif() - endif() - # EXTRA LIBS such that pthread, m, rt - list(APPEND REQUIRED_LIBS ${CHAMELEON_EXTRA_LIBRARIES}) - - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - - # test link - unset(CHAMELEON_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(MORSE_Init CHAMELEON_WORKS) - mark_as_advanced(CHAMELEON_WORKS) - - if(CHAMELEON_WORKS) - # save link with dependencies - set(CHAMELEON_LIBRARIES_DEP "${REQUIRED_LIBS}") - set(CHAMELEON_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") - set(CHAMELEON_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") - set(CHAMELEON_LINKER_FLAGS "${REQUIRED_LDFLAGS}") - list(REMOVE_DUPLICATES CHAMELEON_LIBRARY_DIRS_DEP) - list(REMOVE_DUPLICATES CHAMELEON_INCLUDE_DIRS_DEP) - list(REMOVE_DUPLICATES CHAMELEON_LINKER_FLAGS) - else() - if(NOT CHAMELEON_FIND_QUIETLY) - message(STATUS "Looking for chameleon : test of MORSE_Init fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - message(STATUS "Maybe CHAMELEON is linked with specific libraries. " - "Have you tried with COMPONENTS (STARPU/QUARK, CUDA, MAGMA, MPI, FXT)? " - "See the explanation in FindCHAMELEON.cmake.") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(CHAMELEON_LIBRARIES) - -endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT CHAMELEON_FOUND) OR (CHAMELEON_GIVEN_BY_USER) ) + # If found, add path to cmake variable + # ------------------------------------ + foreach(chameleon_lib ${CHAMELEON_libs_to_find}) -if (CHAMELEON_LIBRARIES) + get_filename_component(${chameleon_lib}_lib_path ${CHAMELEON_${chameleon_lib}_LIBRARY} PATH) + # set cmake variables (respects naming convention) + if (CHAMELEON_LIBRARIES) + list(APPEND CHAMELEON_LIBRARIES "${CHAMELEON_${chameleon_lib}_LIBRARY}") + else() + set(CHAMELEON_LIBRARIES "${CHAMELEON_${chameleon_lib}_LIBRARY}") + endif() if (CHAMELEON_LIBRARY_DIRS) - foreach(dir ${CHAMELEON_LIBRARY_DIRS}) - if ("${dir}" MATCHES "chameleon") - set(first_lib_path "${dir}") - endif() - endforeach() + list(APPEND CHAMELEON_LIBRARY_DIRS "${${chameleon_lib}_lib_path}") else() - list(GET CHAMELEON_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) + set(CHAMELEON_LIBRARY_DIRS "${${chameleon_lib}_lib_path}") + endif() + mark_as_advanced(CHAMELEON_${chameleon_lib}_LIBRARY) + + endforeach(chameleon_lib ${CHAMELEON_libs_to_find}) + + # check a function to validate the find + if(CHAMELEON_LIBRARIES) + + set(REQUIRED_LDFLAGS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # CHAMELEON + if (CHAMELEON_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${CHAMELEON_INCLUDE_DIRS}") endif() - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(CHAMELEON_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of CHAMELEON library" FORCE) + foreach(libdir ${CHAMELEON_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + set(REQUIRED_LIBS "${CHAMELEON_LIBRARIES}") + # STARPU + if (STARPU_FOUND AND CHAMELEON_LOOK_FOR_STARPU) + if (STARPU_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS_DEP}") + elseif (STARPU_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${STARPU_INCLUDE_DIRS}") + endif() + if(STARPU_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS_DEP}") + elseif(STARPU_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${STARPU_LIBRARY_DIRS}") + endif() + if (STARPU_LIBRARIES_DEP) + list(APPEND REQUIRED_LIBS "${STARPU_LIBRARIES_DEP}") + elseif (STARPU_LIBRARIES) + foreach(lib ${STARPU_LIBRARIES}) + if (EXISTS ${lib} OR ${lib} MATCHES "^-") + list(APPEND REQUIRED_LIBS "${lib}") + else() + list(APPEND REQUIRED_LIBS "-l${lib}") + endif() + endforeach() + endif() + endif() + # QUARK + if (QUARK_FOUND AND CHAMELEON_LOOK_FOR_QUARK) + if (QUARK_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${QUARK_INCLUDE_DIRS_DEP}") + elseif(QUARK_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${QUARK_INCLUDE_DIRS}") + endif() + if(QUARK_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${QUARK_LIBRARY_DIRS_DEP}") + elseif(QUARK_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${QUARK_LIBRARY_DIRS}") + endif() + if (QUARK_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBS "${QUARK_LIBRARIES_DEP}") + elseif (QUARK_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBS "${QUARK_LIBRARIES}") + endif() + endif() + # CUDA + if (CUDA_FOUND AND CHAMELEON_LOOK_FOR_CUDA) + if (CUDA_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${CUDA_INCLUDE_DIRS}") + endif() + foreach(libdir ${CUDA_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + list(APPEND REQUIRED_LIBS "${CUDA_CUBLAS_LIBRARIES};${CUDA_LIBRARIES}") + endif() + # MAGMA + if (MAGMA_FOUND AND CHAMELEON_LOOK_FOR_MAGMA) + if (MAGMA_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${MAGMA_INCLUDE_DIRS_DEP}") + elseif(MAGMA_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${MAGMA_INCLUDE_DIRS}") + endif() + if (MAGMA_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${MAGMA_LIBRARY_DIRS_DEP}") + elseif(MAGMA_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${MAGMA_LIBRARY_DIRS}") + endif() + if (MAGMA_LIBRARIES_DEP) + list(APPEND REQUIRED_LIBS "${MAGMA_LIBRARIES_DEP}") + elseif(MAGMA_LIBRARIES) + foreach(lib ${MAGMA_LIBRARIES}) + if (EXISTS ${lib} OR ${lib} MATCHES "^-") + list(APPEND REQUIRED_LIBS "${lib}") + else() + list(APPEND REQUIRED_LIBS "-l${lib}") + endif() + endforeach() + endif() + endif() + # MPI + if (MPI_FOUND AND CHAMELEON_LOOK_FOR_MPI) + if (MPI_C_INCLUDE_PATH) + list(APPEND REQUIRED_INCDIRS "${MPI_C_INCLUDE_PATH}") + endif() + if (MPI_C_LINK_FLAGS) + if (${MPI_C_LINK_FLAGS} MATCHES " -") + string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS}) + endif() + list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}") + endif() + list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}") + endif() + # HWLOC + if (HWLOC_FOUND) + if (HWLOC_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}") + endif() + foreach(libdir ${HWLOC_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + foreach(lib ${HWLOC_LIBRARIES}) + if (EXISTS ${lib} OR ${lib} MATCHES "^-") + list(APPEND REQUIRED_LIBS "${lib}") + else() + list(APPEND REQUIRED_LIBS "-l${lib}") + endif() + endforeach() + endif() + # TMG + if (TMG_FOUND) + if (TMG_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${TMG_INCLUDE_DIRS_DEP}") + elseif (TMG_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${TMG_INCLUDE_DIRS}") + endif() + if(TMG_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${TMG_LIBRARY_DIRS_DEP}") + elseif(TMG_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${TMG_LIBRARY_DIRS}") + endif() + if (TMG_LIBRARIES_DEP) + list(APPEND REQUIRED_LIBS "${TMG_LIBRARIES_DEP}") + elseif(TMG_LIBRARIES) + list(APPEND REQUIRED_LIBS "${TMG_LIBRARIES}") + endif() + if (TMG_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${TMG_LINKER_FLAGS}") + endif() + endif() + # LAPACKE + if (LAPACKE_FOUND) + if (LAPACKE_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${LAPACKE_INCLUDE_DIRS_DEP}") + elseif (LAPACKE_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${LAPACKE_INCLUDE_DIRS}") + endif() + if(LAPACKE_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${LAPACKE_LIBRARY_DIRS_DEP}") + elseif(LAPACKE_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${LAPACKE_LIBRARY_DIRS}") + endif() + if (LAPACKE_LIBRARIES_DEP) + list(APPEND REQUIRED_LIBS "${LAPACKE_LIBRARIES_DEP}") + elseif(LAPACKE_LIBRARIES) + list(APPEND REQUIRED_LIBS "${LAPACKE_LIBRARIES}") + endif() + if (LAPACK_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") + endif() + endif() + # CBLAS + if (CBLAS_FOUND) + if (CBLAS_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS_DEP}") + elseif (CBLAS_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS}") + endif() + if(CBLAS_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS_DEP}") + elseif(CBLAS_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS}") + endif() + if (CBLAS_LIBRARIES_DEP) + list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES_DEP}") + elseif(CBLAS_LIBRARIES) + list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES}") + endif() + if (BLAS_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") + endif() + endif() + # EXTRA LIBS such that pthread, m, rt + list(APPEND REQUIRED_LIBS ${CHAMELEON_EXTRA_LIBRARIES}) + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(CHAMELEON_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(MORSE_Init CHAMELEON_WORKS) + mark_as_advanced(CHAMELEON_WORKS) + + if(CHAMELEON_WORKS) + # save link with dependencies + set(CHAMELEON_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(CHAMELEON_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(CHAMELEON_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(CHAMELEON_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES CHAMELEON_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES CHAMELEON_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES CHAMELEON_LINKER_FLAGS) else() - set(CHAMELEON_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of CHAMELEON library" FORCE) + if(NOT CHAMELEON_FIND_QUIETLY) + message(STATUS "Looking for chameleon : test of MORSE_Init fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + message(STATUS "Maybe CHAMELEON is linked with specific libraries. " + "Have you tried with COMPONENTS (STARPU/QUARK, CUDA, MAGMA, MPI, FXT)? " + "See the explanation in FindCHAMELEON.cmake.") + endif() endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(CHAMELEON_LIBRARIES) + +endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT CHAMELEON_FOUND) OR (CHAMELEON_GIVEN_BY_USER) ) + +if (CHAMELEON_LIBRARIES) + if (CHAMELEON_LIBRARY_DIRS) + foreach(dir ${CHAMELEON_LIBRARY_DIRS}) + if ("${dir}" MATCHES "chameleon") + set(first_lib_path "${dir}") + endif() + endforeach() + else() + list(GET CHAMELEON_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(CHAMELEON_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of CHAMELEON library" FORCE) + else() + set(CHAMELEON_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of CHAMELEON library" FORCE) + endif() endif() +mark_as_advanced(CHAMELEON_DIR) +mark_as_advanced(CHAMELEON_DIR_FOUND) # check that CHAMELEON has been found # --------------------------------- include(FindPackageHandleStandardArgs) if (PKG_CONFIG_EXECUTABLE AND CHAMELEON_FOUND) - find_package_handle_standard_args(CHAMELEON DEFAULT_MSG - CHAMELEON_LIBRARIES) + find_package_handle_standard_args(CHAMELEON DEFAULT_MSG + CHAMELEON_LIBRARIES) else() - find_package_handle_standard_args(CHAMELEON DEFAULT_MSG - CHAMELEON_LIBRARIES - CHAMELEON_WORKS) + find_package_handle_standard_args(CHAMELEON DEFAULT_MSG + CHAMELEON_LIBRARIES + CHAMELEON_WORKS) endif() diff --git a/CMakeModules/morse/find/FindEZTRACE.cmake b/CMakeModules/morse/find/FindEZTRACE.cmake index bfcdf34e5c1904b5c058f5a4002eee00fb8b89b7..7584c5e9f7f2d9ba42a272593134a1126c08d0f2 100644 --- a/CMakeModules/morse/find/FindEZTRACE.cmake +++ b/CMakeModules/morse/find/FindEZTRACE.cmake @@ -50,10 +50,10 @@ # License text for the above reference.) if (NOT EZTRACE_FOUND) - set(EZTRACE_DIR "" CACHE PATH "Installation directory of EZTRACE library") - if (NOT EZTRACE_FIND_QUIETLY) - message(STATUS "A cache variable, namely EZTRACE_DIR, has been set to specify the install directory of EZTRACE") - endif() + set(EZTRACE_DIR "" CACHE PATH "Installation directory of EZTRACE library") + if (NOT EZTRACE_FIND_QUIETLY) + message(STATUS "A cache variable, namely EZTRACE_DIR, has been set to specify the install directory of EZTRACE") + endif() endif() set(ENV_EZTRACE_DIR "$ENV{EZTRACE_DIR}") @@ -61,7 +61,7 @@ set(ENV_EZTRACE_INCDIR "$ENV{EZTRACE_INCDIR}") set(ENV_EZTRACE_LIBDIR "$ENV{EZTRACE_LIBDIR}") set(EZTRACE_GIVEN_BY_USER "FALSE") if ( EZTRACE_DIR OR ( EZTRACE_INCDIR AND EZTRACE_LIBDIR) OR ENV_EZTRACE_DIR OR (ENV_EZTRACE_INCDIR AND ENV_EZTRACE_LIBDIR) ) - set(EZTRACE_GIVEN_BY_USER "TRUE") + set(EZTRACE_GIVEN_BY_USER "TRUE") endif() # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) @@ -70,284 +70,286 @@ include(FindPkgConfig) find_package(PkgConfig QUIET) if( PKG_CONFIG_EXECUTABLE AND NOT EZTRACE_GIVEN_BY_USER ) - pkg_search_module(EZTRACE eztrace) - if (NOT EZTRACE_FIND_QUIETLY) - if (EZTRACE_FOUND AND EZTRACE_LIBRARIES) - message(STATUS "Looking for EZTRACE - found using PkgConfig") - #if(NOT EZTRACE_INCLUDE_DIRS) - # message("${Magenta}EZTRACE_INCLUDE_DIRS is empty using PkgConfig." - # "Perhaps the path to eztrace headers is already present in your" - # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") - #endif() - else() - message("${Magenta}Looking for EZTRACE - not found using PkgConfig." - "Perhaps you should add the directory containing eztrace.pc to" - "the PKG_CONFIG_PATH environment variable.${ColourReset}") - endif() + pkg_search_module(EZTRACE eztrace) + if (NOT EZTRACE_FIND_QUIETLY) + if (EZTRACE_FOUND AND EZTRACE_LIBRARIES) + message(STATUS "Looking for EZTRACE - found using PkgConfig") + #if(NOT EZTRACE_INCLUDE_DIRS) + # message("${Magenta}EZTRACE_INCLUDE_DIRS is empty using PkgConfig." + # "Perhaps the path to eztrace headers is already present in your" + # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") + #endif() + else() + message(STATUS "${Magenta}Looking for EZTRACE - not found using PkgConfig." + "\n Perhaps you should add the directory containing eztrace.pc to" + "\n the PKG_CONFIG_PATH environment variable.${ColourReset}") endif() + endif() endif( PKG_CONFIG_EXECUTABLE AND NOT EZTRACE_GIVEN_BY_USER ) if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT EZTRACE_FOUND) OR (EZTRACE_GIVEN_BY_USER) ) - if (NOT EZTRACE_FIND_QUIETLY) - message(STATUS "Looking for EZTRACE - PkgConfig not used") + if (NOT EZTRACE_FIND_QUIETLY) + message(STATUS "Looking for EZTRACE - PkgConfig not used") + endif() + + # Looking for libbfd + # ------------------ + + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() + list(REMOVE_DUPLICATES _lib_env) + + # set paths where to look for + set(PATH_TO_LOOK_FOR "${_lib_env}") + + # Try to find the bfd lib in the given paths + # ------------------------------------------ + + # call cmake macro to find the lib path + set(EZTRACE_bfd_LIBRARY "EZTRACE_bfd_LIBRARY-NOTFOUND") + find_library(EZTRACE_bfd_LIBRARY + NAMES bfd + HINTS ${PATH_TO_LOOK_FOR}) + mark_as_advanced(EZTRACE_bfd_LIBRARY) + + if (NOT EZTRACE_bfd_LIBRARY) + if(NOT EZTRACE_FIND_QUIETLY) + message(STATUS "Looking for eztrace -- lib bfd not found") endif() + endif () + + # Looking for include + # ------------------- + + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + if(ENV_EZTRACE_INCDIR) + list(APPEND _inc_env "${ENV_EZTRACE_INCDIR}") + elseif(ENV_EZTRACE_DIR) + list(APPEND _inc_env "${ENV_EZTRACE_DIR}") + list(APPEND _inc_env "${ENV_EZTRACE_DIR}/include") + list(APPEND _inc_env "${ENV_EZTRACE_DIR}/include/eztrace") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) + + # set paths where to look for + set(PATH_TO_LOOK_FOR "${_inc_env}") + + # Try to find the eztrace header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(EZTRACE_INCDIR) + set(EZTRACE_eztrace.h_DIRS "EZTRACE_eztrace.h_DIRS-NOTFOUND") + find_path(EZTRACE_eztrace.h_DIRS + NAMES eztrace.h + HINTS ${EZTRACE_INCDIR}) + else() + if(EZTRACE_DIR) + set(EZTRACE_eztrace.h_DIRS "EZTRACE_eztrace.h_DIRS-NOTFOUND") + find_path(EZTRACE_eztrace.h_DIRS + NAMES eztrace.h + HINTS ${EZTRACE_DIR} + PATH_SUFFIXES "include" "include/eztrace") + else() + set(EZTRACE_eztrace.h_DIRS "EZTRACE_eztrace.h_DIRS-NOTFOUND") + find_path(EZTRACE_eztrace.h_DIRS + NAMES eztrace.h + HINTS ${PATH_TO_LOOK_FOR} + PATH_SUFFIXES "eztrace") + endif() + endif() + mark_as_advanced(EZTRACE_eztrace.h_DIRS) + + # Add path to cmake variable + # ------------------------------------ + if (EZTRACE_eztrace.h_DIRS) + set(EZTRACE_INCLUDE_DIRS "${EZTRACE_eztrace.h_DIRS}") + else () + set(EZTRACE_INCLUDE_DIRS "EZTRACE_INCLUDE_DIRS-NOTFOUND") + if(NOT EZTRACE_FIND_QUIETLY) + message(STATUS "Looking for eztrace -- eztrace.h not found") + endif() + endif () + + if (EZTRACE_INCLUDE_DIRS) + list(REMOVE_DUPLICATES EZTRACE_INCLUDE_DIRS) + endif () + - # Looking for libbfd - # ------------------ + # Looking for lib + # --------------- - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + if(ENV_EZTRACE_LIBDIR) + list(APPEND _lib_env "${ENV_EZTRACE_LIBDIR}") + elseif(ENV_EZTRACE_DIR) + list(APPEND _lib_env "${ENV_EZTRACE_DIR}") + list(APPEND _lib_env "${ENV_EZTRACE_DIR}/lib") + else() if(WIN32) string(REPLACE ":" ";" _lib_env "$ENV{LIB}") else() if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") endif() list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") endif() - list(REMOVE_DUPLICATES _lib_env) - - # set paths where to look for - set(PATH_TO_LOOK_FOR "${_lib_env}") - - # Try to find the bfd lib in the given paths - # ------------------------------------------ - - # call cmake macro to find the lib path - set(EZTRACE_bfd_LIBRARY "EZTRACE_bfd_LIBRARY-NOTFOUND") - find_library(EZTRACE_bfd_LIBRARY - NAMES bfd - HINTS ${PATH_TO_LOOK_FOR}) - mark_as_advanced(EZTRACE_bfd_LIBRARY) - - if (NOT EZTRACE_bfd_LIBRARY) - if(NOT EZTRACE_FIND_QUIETLY) - message(STATUS "Looking for eztrace -- lib bfd not found") - endif() - endif () - - # Looking for include - # ------------------- - - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - if(ENV_EZTRACE_INCDIR) - list(APPEND _inc_env "${ENV_EZTRACE_INCDIR}") - elseif(ENV_EZTRACE_DIR) - list(APPEND _inc_env "${ENV_EZTRACE_DIR}") - list(APPEND _inc_env "${ENV_EZTRACE_DIR}/include") - list(APPEND _inc_env "${ENV_EZTRACE_DIR}/include/eztrace") + endif() + list(REMOVE_DUPLICATES _lib_env) + + # set paths where to look for + set(PATH_TO_LOOK_FOR "${_lib_env}") + + # Try to find the eztrace lib in the given paths + # ---------------------------------------------- + + # call cmake macro to find the lib path + if(EZTRACE_LIBDIR) + set(EZTRACE_eztrace_LIBRARY "EZTRACE_eztrace_LIBRARY-NOTFOUND") + find_library(EZTRACE_eztrace_LIBRARY + NAMES eztrace + HINTS ${EZTRACE_LIBDIR}) + else() + if(EZTRACE_DIR) + set(EZTRACE_eztrace_LIBRARY "EZTRACE_eztrace_LIBRARY-NOTFOUND") + find_library(EZTRACE_eztrace_LIBRARY + NAMES eztrace + HINTS ${EZTRACE_DIR} + PATH_SUFFIXES lib lib32 lib64) else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + set(EZTRACE_eztrace_LIBRARY "EZTRACE_eztrace_LIBRARY-NOTFOUND") + find_library(EZTRACE_eztrace_LIBRARY + NAMES eztrace + HINTS ${PATH_TO_LOOK_FOR}) endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) - - # set paths where to look for - set(PATH_TO_LOOK_FOR "${_inc_env}") - - # Try to find the eztrace header in the given paths - # ------------------------------------------------- - # call cmake macro to find the header path - if(EZTRACE_INCDIR) - set(EZTRACE_eztrace.h_DIRS "EZTRACE_eztrace.h_DIRS-NOTFOUND") - find_path(EZTRACE_eztrace.h_DIRS - NAMES eztrace.h - HINTS ${EZTRACE_INCDIR}) - else() - if(EZTRACE_DIR) - set(EZTRACE_eztrace.h_DIRS "EZTRACE_eztrace.h_DIRS-NOTFOUND") - find_path(EZTRACE_eztrace.h_DIRS - NAMES eztrace.h - HINTS ${EZTRACE_DIR} - PATH_SUFFIXES "include" "include/eztrace") - else() - set(EZTRACE_eztrace.h_DIRS "EZTRACE_eztrace.h_DIRS-NOTFOUND") - find_path(EZTRACE_eztrace.h_DIRS - NAMES eztrace.h - HINTS ${PATH_TO_LOOK_FOR} - PATH_SUFFIXES "eztrace") - endif() + endif() + mark_as_advanced(EZTRACE_eztrace_LIBRARY) + + # If found, add path to cmake variable + # ------------------------------------ + if (EZTRACE_eztrace_LIBRARY) + get_filename_component(eztrace_lib_path ${EZTRACE_eztrace_LIBRARY} PATH) + # set cmake variables (respects naming convention) + set(EZTRACE_LIBRARIES "${EZTRACE_eztrace_LIBRARY}") + set(EZTRACE_LIBRARY_DIRS "${eztrace_lib_path}") + else () + set(EZTRACE_LIBRARIES "EZTRACE_LIBRARIES-NOTFOUND") + set(EZTRACE_LIBRARY_DIRS "EZTRACE_LIBRARY_DIRS-NOTFOUND") + if(NOT EZTRACE_FIND_QUIETLY) + message(STATUS "Looking for eztrace -- lib eztrace not found") endif() - mark_as_advanced(EZTRACE_eztrace.h_DIRS) - - # Add path to cmake variable - # ------------------------------------ - if (EZTRACE_eztrace.h_DIRS) - set(EZTRACE_INCLUDE_DIRS "${EZTRACE_eztrace.h_DIRS}") - else () - set(EZTRACE_INCLUDE_DIRS "EZTRACE_INCLUDE_DIRS-NOTFOUND") - if(NOT EZTRACE_FIND_QUIETLY) - message(STATUS "Looking for eztrace -- eztrace.h not found") - endif() - endif () - - if (EZTRACE_INCLUDE_DIRS) - list(REMOVE_DUPLICATES EZTRACE_INCLUDE_DIRS) - endif () + endif () + if (EZTRACE_LIBRARY_DIRS) + list(REMOVE_DUPLICATES EZTRACE_LIBRARY_DIRS) + endif () - # Looking for lib - # --------------- + # check a function to validate the find + if(EZTRACE_LIBRARIES) - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - if(ENV_EZTRACE_LIBDIR) - list(APPEND _lib_env "${ENV_EZTRACE_LIBDIR}") - elseif(ENV_EZTRACE_DIR) - list(APPEND _lib_env "${ENV_EZTRACE_DIR}") - list(APPEND _lib_env "${ENV_EZTRACE_DIR}/lib") - else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() - endif() - list(REMOVE_DUPLICATES _lib_env) - - # set paths where to look for - set(PATH_TO_LOOK_FOR "${_lib_env}") - - # Try to find the eztrace lib in the given paths - # ---------------------------------------------- + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) - # call cmake macro to find the lib path - if(EZTRACE_LIBDIR) - set(EZTRACE_eztrace_LIBRARY "EZTRACE_eztrace_LIBRARY-NOTFOUND") - find_library(EZTRACE_eztrace_LIBRARY - NAMES eztrace - HINTS ${EZTRACE_LIBDIR}) - else() - if(EZTRACE_DIR) - set(EZTRACE_eztrace_LIBRARY "EZTRACE_eztrace_LIBRARY-NOTFOUND") - find_library(EZTRACE_eztrace_LIBRARY - NAMES eztrace - HINTS ${EZTRACE_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(EZTRACE_eztrace_LIBRARY "EZTRACE_eztrace_LIBRARY-NOTFOUND") - find_library(EZTRACE_eztrace_LIBRARY - NAMES eztrace - HINTS ${PATH_TO_LOOK_FOR}) - endif() + # EZTRACE + if (EZTRACE_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${EZTRACE_INCLUDE_DIRS}") endif() - mark_as_advanced(EZTRACE_eztrace_LIBRARY) - - # If found, add path to cmake variable - # ------------------------------------ - if (EZTRACE_eztrace_LIBRARY) - get_filename_component(eztrace_lib_path ${EZTRACE_eztrace_LIBRARY} PATH) - # set cmake variables (respects naming convention) - set(EZTRACE_LIBRARIES "${EZTRACE_eztrace_LIBRARY}") - set(EZTRACE_LIBRARY_DIRS "${eztrace_lib_path}") - else () - set(EZTRACE_LIBRARIES "EZTRACE_LIBRARIES-NOTFOUND") - set(EZTRACE_LIBRARY_DIRS "EZTRACE_LIBRARY_DIRS-NOTFOUND") - if(NOT EZTRACE_FIND_QUIETLY) - message(STATUS "Looking for eztrace -- lib eztrace not found") - endif() - endif () - if (EZTRACE_LIBRARY_DIRS) - list(REMOVE_DUPLICATES EZTRACE_LIBRARY_DIRS) - endif () - - # check a function to validate the find - if(EZTRACE_LIBRARIES) - - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) - - # EZTRACE - if (EZTRACE_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${EZTRACE_INCLUDE_DIRS}") - endif() - if (EZTRACE_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${EZTRACE_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${EZTRACE_LIBRARIES}") - - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - - # test link - unset(EZTRACE_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(eztrace_start EZTRACE_WORKS) - mark_as_advanced(EZTRACE_WORKS) - - if(NOT EZTRACE_WORKS) - if(NOT EZTRACE_FIND_QUIETLY) - message(STATUS "Looking for eztrace : test of eztrace_topology_init with eztrace library fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(EZTRACE_LIBRARIES) + set(REQUIRED_LIBDIRS "${EZTRACE_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${EZTRACE_LIBRARIES}") + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(EZTRACE_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(eztrace_start EZTRACE_WORKS) + mark_as_advanced(EZTRACE_WORKS) + + if(NOT EZTRACE_WORKS) + if(NOT EZTRACE_FIND_QUIETLY) + message(STATUS "Looking for eztrace : test of eztrace_topology_init with eztrace library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(EZTRACE_LIBRARIES) endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT EZTRACE_FOUND) OR (EZTRACE_GIVEN_BY_USER) ) if (EZTRACE_LIBRARIES) - if (EZTRACE_LIBRARY_DIRS) - list(GET EZTRACE_LIBRARY_DIRS 0 first_lib_path) - else() - list(GET EZTRACE_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - endif() - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(EZTRACE_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of EZTRACE library" FORCE) - else() - set(EZTRACE_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of EZTRACE library" FORCE) - endif() + if (EZTRACE_LIBRARY_DIRS) + list(GET EZTRACE_LIBRARY_DIRS 0 first_lib_path) + else() + list(GET EZTRACE_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(EZTRACE_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of EZTRACE library" FORCE) + else() + set(EZTRACE_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of EZTRACE library" FORCE) + endif() endif() +mark_as_advanced(EZTRACE_DIR) +mark_as_advanced(EZTRACE_DIR_FOUND) # check that EZTRACE has been found # ------------------------------- include(FindPackageHandleStandardArgs) if (PKG_CONFIG_EXECUTABLE AND EZTRACE_FOUND) - find_package_handle_standard_args(EZTRACE DEFAULT_MSG - EZTRACE_LIBRARIES) + find_package_handle_standard_args(EZTRACE DEFAULT_MSG + EZTRACE_LIBRARIES) else() - find_package_handle_standard_args(EZTRACE DEFAULT_MSG - EZTRACE_LIBRARIES - EZTRACE_WORKS) + find_package_handle_standard_args(EZTRACE DEFAULT_MSG + EZTRACE_LIBRARIES + EZTRACE_WORKS) endif() diff --git a/CMakeModules/morse/find/FindFFTW.cmake b/CMakeModules/morse/find/FindFFTW.cmake index f187b7c80d788a03a9d4df2be2f337884346501a..a9d8b1918a5a3be1e66efa20fd0df8c8abfef68a 100644 --- a/CMakeModules/morse/find/FindFFTW.cmake +++ b/CMakeModules/morse/find/FindFFTW.cmake @@ -9,6 +9,8 @@ ### # # - Find FFTW Version 3 include dirs and libraries +# Default configuration will find the real double precision fftw library version +# without THREADS|OMP. # Use this module by invoking find_package with the form: # find_package(FFTW # [REQUIRED] # Fail with error if fftw is not found @@ -16,10 +18,10 @@ # # COMPONENTS can be some of the following: # - MKL: to detect the FFTW from Intel MKL +# - ESSL: to detect the FFTW from IBM ESSL # - THREADS: to detect the Threads version of FFTW # - OMP: to detect the OpenMP version of FFTW # - SIMPLE: to detect the FFTW simple precision fftw3f -# - DOUBLE: to detect the FFTW double precision fftw3 (default) # - LONG: to detect the FFTW long double precision fftw3l # - QUAD: to detect the FFTW quadruple precision fftw3q # @@ -50,7 +52,7 @@ # Copyright 2012-2013 Emmanuel Agullo # Copyright 2012-2013 Mathieu Faverge # Copyright 2012 Cedric Castagnede -# Copyright 2013 Florent Pruvost +# Copyright 2013-2016 Florent Pruvost # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file MORSE-Copyright.txt for details. @@ -72,10 +74,10 @@ endif() # Set the version to find set(FFTW_LOOK_FOR_MKL OFF) +set(FFTW_LOOK_FOR_ESSL OFF) set(FFTW_LOOK_FOR_THREADS OFF) set(FFTW_LOOK_FOR_OMP OFF) set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF) -set(FFTW_LOOK_FOR_FFTW_DOUBLE ON) set(FFTW_LOOK_FOR_FFTW_LONG OFF) set(FFTW_LOOK_FOR_FFTW_QUAD OFF) @@ -92,28 +94,18 @@ if( FFTW_FIND_COMPONENTS ) if (${component} STREQUAL "SIMPLE") # means we look for FFTW simple precision (fftw3f) set(FFTW_LOOK_FOR_FFTW_SIMPLE ON) - set(FFTW_LOOK_FOR_FFTW_DOUBLE OFF) - set(FFTW_LOOK_FOR_FFTW_LONG OFF) - set(FFTW_LOOK_FOR_FFTW_QUAD OFF) - endif() - if (${component} STREQUAL "DOUBLE") - # means we look for FFTW double precision (fftw3) - set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF) - set(FFTW_LOOK_FOR_FFTW_DOUBLE ON) set(FFTW_LOOK_FOR_FFTW_LONG OFF) set(FFTW_LOOK_FOR_FFTW_QUAD OFF) endif() if (${component} STREQUAL "LONG") # means we look for FFTW long double precision (fftw3l) set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF) - set(FFTW_LOOK_FOR_FFTW_DOUBLE OFF) set(FFTW_LOOK_FOR_FFTW_LONG ON) set(FFTW_LOOK_FOR_FFTW_QUAD OFF) endif() if (${component} STREQUAL "QUAD") # means we look for FFTW quad precision (fftw3q) set(FFTW_LOOK_FOR_FFTW_SIMPLE OFF) - set(FFTW_LOOK_FOR_FFTW_DOUBLE OFF) set(FFTW_LOOK_FOR_FFTW_LONG OFF) set(FFTW_LOOK_FOR_FFTW_QUAD ON) endif() @@ -121,18 +113,47 @@ if( FFTW_FIND_COMPONENTS ) # means we look for the Intel MKL version of FFTW set(FFTW_LOOK_FOR_MKL ON) if (FFTW_LOOK_FOR_FFTW_LONG) - message(WARNING "Looking for FFTW -- long precision functions do not exist in MKL FFTW") + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "Looking for FFTW -- long precision functions do not exist in MKL FFTW") + endif() set(FFTW_LOOK_FOR_FFTW_LONG OFF) endif() if (FFTW_LOOK_FOR_FFTW_QUAD) - message(WARNING "Looking for FFTW -- quadruple functions do not exist in MKL FFTW") + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "Looking for FFTW -- quadruple functions do not exist in MKL FFTW") + endif() set(FFTW_LOOK_FOR_FFTW_QUAD OFF) endif() endif() + if (${component} STREQUAL "ESSL") + # means we look for the Intel MKL version of FFTW + set(FFTW_LOOK_FOR_ESSL ON) + if (FFTW_LOOK_FOR_FFTW_LONG) + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "Looking for FFTW -- long precision functions do not exist in FFTW_ESSL") + endif() + set(FFTW_LOOK_FOR_FFTW_LONG OFF) + endif() + if (FFTW_LOOK_FOR_FFTW_QUAD) + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "Looking for FFTW -- quadruple functions do not exist in FFTW_ESSL") + endif() + set(FFTW_LOOK_FOR_FFTW_QUAD OFF) + endif() + if (FFTW_LOOK_FOR_OMP) + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "Looking for FFTW -- FFTW_ESSL does not use OpenMP") + endif() + set(FFTW_LOOK_FOR_OMP OFF) + endif() + endif() endforeach() endif() if (FFTW_LOOK_FOR_THREADS) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "FFTW looks for threads") + endif() if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_THREADS) find_package(Threads REQUIRED) else() @@ -140,23 +161,51 @@ if (FFTW_LOOK_FOR_THREADS) endif() endif() +if (FFTW_LOOK_FOR_OMP) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "FFTW looks for openmp") + endif() + if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_OMP) + find_package(OpenMP REQUIRED) + else() + find_package(OpenMP) + endif() +endif() + if (FFTW_LOOK_FOR_MKL) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "FFTW looks for threads and Intel MKL") + endif() + if (FFTW_LOOK_FOR_THREADS) + set(BLA_VENDOR "Intel10_64lp") + else() + set(BLA_VENDOR "Intel10_64lp_seq") + endif() if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL) find_package(Threads REQUIRED) + find_package(BLASEXT REQUIRED) else() find_package(Threads) + find_package(BLASEXT) endif() endif() -if (FFTW_LOOK_FOR_OMP) - if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_OMP) - find_package(OpenMP REQUIRED) +if (FFTW_LOOK_FOR_ESSL) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "FFTW looks for IBM ESSL") + endif() + if (FFTW_LOOK_FOR_THREADS) + set(BLA_VENDOR "IBMESSLMT") else() - find_package(OpenMP) + set(BLA_VENDOR "IBMESSL") + endif() + if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_ESSL) + find_package(BLASEXT REQUIRED) + else() + find_package(BLASEXT) endif() endif() - set(ENV_FFTW_DIR "$ENV{FFTW_DIR}") set(ENV_FFTW_INCDIR "$ENV{FFTW_INCDIR}") set(ENV_FFTW_LIBDIR "$ENV{FFTW_LIBDIR}") @@ -165,46 +214,153 @@ if ( FFTW_DIR OR ( FFTW_INCDIR AND FFTW_LIBDIR) OR ENV_FFTW_DIR OR (ENV_FFTW_INC set(FFTW_GIVEN_BY_USER "TRUE") endif() + # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) # ------------------------------------------------------------------------------------- -include(FindPkgConfig) -find_package(PkgConfig QUIET) -if( PKG_CONFIG_EXECUTABLE AND NOT FFTW_GIVEN_BY_USER ) - - if(FFTW_LOOK_FOR_FFTW_SIMPLE) - pkg_search_module(FFTW fftw3f) - elseif(FFTW_LOOK_FOR_FFTW_LONG) - pkg_search_module(FFTW fftw3) - elseif(FFTW_LOOK_FOR_FFTW_QUAD) - pkg_search_module(FFTW fftw3q) - else() - pkg_search_module(FFTW fftw3) - endif() - - if (NOT FFTW_FIND_QUIETLY) - if (FFTW_FOUND AND FFTW_LIBRARIES) - message(STATUS "Looking for FFTW - found using PkgConfig") - #if(NOT FFTW_INCLUDE_DIRS) - # message("${Magenta}FFTW_INCLUDE_DIRS is empty using PkgConfig." - # "Perhaps the path to hwloc headers is already present in your" - # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") - #endif() +if (NOT FFTW_LOOK_FOR_MKL AND NOT FFTW_LOOK_FOR_ESSL) + include(FindPkgConfig) + find_package(PkgConfig QUIET) + if( PKG_CONFIG_EXECUTABLE AND NOT FFTW_GIVEN_BY_USER ) + + set(FFTW_INCLUDE_DIRS) + set(FFTW_LIBRARY_DIRS) + set(FFTW_LIBRARIES) + + if(FFTW_LOOK_FOR_FFTW_SIMPLE) + pkg_search_module(FFTW3F fftw3f) + pkg_search_module(FFTW3 fftw3) + if (FFTW3F_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3F - found using PkgConfig") + endif() + if (FFTW3F_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${FFTW3F_LIBRARIES}") + endif() + if(FFTW3F_INCLUDE_DIRS) + list(APPEND FFTW_INCLUDE_DIRS "${FFTW3F_INCLUDE_DIRS}") + else() + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "FFTW3F_INCLUDE_DIRS is empty using PkgConfig." + "Perhaps the path to fftw3f headers is already present in your" + "CPATH/C(PLUS)_INCLUDE_PATH environment variables.") + endif() + endif() + if(FFTW3F_LIBRARY_DIRS) + list(APPEND FFTW_LIBRARY_DIRS "${FFTW3F_LIBRARY_DIRS}") + endif() + else(FFTW3F_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3F - not found using PkgConfig." + "\n Perhaps you should add the directory containing fftw3f.pc to" + "\n the PKG_CONFIG_PATH environment variable.") + endif() + endif(FFTW3F_FOUND) + elseif(FFTW_LOOK_FOR_FFTW_LONG) + pkg_search_module(FFTW3L fftw3l) + pkg_search_module(FFTW3 fftw3) + if (FFTW3L_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3L - found using PkgConfig") + endif() + if (FFTW3L_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${FFTW3L_LIBRARIES}") + endif() + if(FFTW3L_INCLUDE_DIRS) + list(APPEND FFTW_INCLUDE_DIRS "${FFTW3L_INCLUDE_DIRS}") + else() + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "FFTW3L_INCLUDE_DIRS is empty using PkgConfig." + "Perhaps the path to fftw3l headers is already present in your" + "CPATH/C(PLUS)_INCLUDE_PATH environment variables.") + endif() + endif() + if(FFTW3L_LIBRARY_DIRS) + list(APPEND FFTW_LIBRARY_DIRS "${FFTW3L_LIBRARY_DIRS}") + endif() + else(FFTW3L_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3L - not found using PkgConfig." + "\n Perhaps you should add the directory containing fftw3l.pc to" + "\n the PKG_CONFIG_PATH environment variable.") + endif() + endif(FFTW3L_FOUND) + elseif(FFTW_LOOK_FOR_FFTW_QUAD) + pkg_search_module(FFTW3Q fftw3q) + pkg_search_module(FFTW3 fftw3) + if (FFTW3Q_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3Q - found using PkgConfig") + endif() + if (FFTW3Q_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${FFTW3Q_LIBRARIES}") + endif() + if(FFTW3Q_INCLUDE_DIRS) + list(APPEND FFTW_INCLUDE_DIRS "${FFTW3Q_INCLUDE_DIRS}") + else() + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "FFTW3Q_INCLUDE_DIRS is empty using PkgConfig." + "Perhaps the path to fftw3q headers is already present in your" + "CPATH/C(PLUS)_INCLUDE_PATH environment variables.") + endif() + endif() + if(FFTW3Q_LIBRARY_DIRS) + list(APPEND FFTW_LIBRARY_DIRS "${FFTW3Q_LIBRARY_DIRS}") + endif() + else(FFTW3Q_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3Q - not found using PkgConfig." + "\n Perhaps you should add the directory containing fftw3q.pc to" + "\n the PKG_CONFIG_PATH environment variable.") + endif() + endif(FFTW3Q_FOUND) else() - message("${Magenta}Looking for FFTW - not found using PkgConfig." - "Perhaps you should add the directory containing fftw3.pc to" - "the PKG_CONFIG_PATH environment variable.${ColourReset}") + pkg_search_module(FFTW3 fftw3) endif() - endif() + if (FFTW3_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3 - found using PkgConfig") + endif() + if (FFTW3_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${FFTW3_LIBRARIES}") + endif() + if(FFTW3_INCLUDE_DIRS) + list(APPEND FFTW_INCLUDE_DIRS "${FFTW3_INCLUDE_DIRS}") + else() + if (NOT FFTW_FIND_QUIETLY) + message(WARNING "FFTW3_INCLUDE_DIRS is empty using PkgConfig." + "Perhaps the path to fftw3 headers is already present in your" + "CPATH/C(PLUS)_INCLUDE_PATH environment variables.") + endif() + endif() + if(FFTW3_LIBRARY_DIRS) + list(APPEND FFTW_LIBRARY_DIRS "${FFTW3_LIBRARY_DIRS}") + endif() + else(FFTW3_FOUND) + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW3 - not found using PkgConfig." + "\n Perhaps you should add the directory containing fftw3.pc to" + "\n the PKG_CONFIG_PATH environment variable.") + endif() + endif(FFTW3_FOUND) - set(FFTW_INCLUDE_DIRS_DEP "${FFTW_INCLUDE_DIRS}") - set(FFTW_LIBRARY_DIRS_DEP "${FFTW_LIBRARY_DIRS}") - set(FFTW_LIBRARIES_DEP "${FFTW_LIBRARIES}") - set(FFTW_WORKS TRUE) + set(FFTW_INCLUDE_DIRS_DEP "${FFTW_INCLUDE_DIRS}") + set(FFTW_LIBRARY_DIRS_DEP "${FFTW_LIBRARY_DIRS}") + set(FFTW_LIBRARIES_DEP "${FFTW_LIBRARIES}" ) -endif( PKG_CONFIG_EXECUTABLE AND NOT FFTW_GIVEN_BY_USER ) + if (FFTW_LIBRARIES) + set(FFTW_WORKS TRUE) + endif() + endif( PKG_CONFIG_EXECUTABLE AND NOT FFTW_GIVEN_BY_USER ) -if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR (FFTW_GIVEN_BY_USER) ) +endif(NOT FFTW_LOOK_FOR_MKL AND NOT FFTW_LOOK_FOR_ESSL) + +if( (NOT PKG_CONFIG_EXECUTABLE) OR + (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR + FFTW_GIVEN_BY_USER OR + FFTW_LOOK_FOR_MKL OR + FFTW_LOOK_FOR_ESSL + ) # Looking for include # ------------------- @@ -247,39 +403,45 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR # set paths where to look for set(PATH_TO_LOOK_FOR "${_inc_env}") + if (FFTW_LOOK_FOR_ESSL) + set(FFTW3_HEADER_TO_FIND "fftw3_essl.h") + else() + set(FFTW3_HEADER_TO_FIND "fftw3.h") + endif() + # Try to find the fftw header in the given paths # ------------------------------------------------- # call cmake macro to find the header path if(FFTW_INCDIR) - set(FFTW_fftw3.h_DIRS "FFTW_fftw3.h_DIRS-NOTFOUND") - find_path(FFTW_fftw3.h_DIRS - NAMES fftw3.h + set(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS "FFTW_${FFTW3_HEADER_TO_FIND}_DIRS-NOTFOUND") + find_path(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS + NAMES ${FFTW3_HEADER_TO_FIND} HINTS ${FFTW_INCDIR}) else() if(FFTW_DIR) - set(FFTW_fftw3.h_DIRS "FFTW_fftw3.h_DIRS-NOTFOUND") - find_path(FFTW_fftw3.h_DIRS - NAMES fftw3.h + set(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS "FFTW_${FFTW3_HEADER_TO_FIND}_DIRS-NOTFOUND") + find_path(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS + NAMES ${FFTW3_HEADER_TO_FIND} HINTS ${FFTW_DIR} PATH_SUFFIXES "include" "include/fftw") else() - set(FFTW_fftw3.h_DIRS "FFTW_fftw3.h_DIRS-NOTFOUND") - find_path(FFTW_fftw3.h_DIRS - NAMES fftw3.h + set(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS "FFTW_${FFTW3_HEADER_TO_FIND}_DIRS-NOTFOUND") + find_path(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS + NAMES ${FFTW3_HEADER_TO_FIND} HINTS ${PATH_TO_LOOK_FOR} PATH_SUFFIXES "fftw") endif() endif() - mark_as_advanced(FFTW_fftw3.h_DIRS) + mark_as_advanced(FFTW_${FFTW3_HEADER_TO_FIND}_DIRS) # Add path to cmake variable # ------------------------------------ - if (FFTW_fftw3.h_DIRS) - set(FFTW_INCLUDE_DIRS "${FFTW_fftw3.h_DIRS}") + if (FFTW_${FFTW3_HEADER_TO_FIND}_DIRS) + set(FFTW_INCLUDE_DIRS "${FFTW_${FFTW3_HEADER_TO_FIND}_DIRS}") else () set(FFTW_INCLUDE_DIRS "FFTW_INCLUDE_DIRS-NOTFOUND") if(NOT FFTW_FIND_QUIETLY) - message(STATUS "Looking for FFTW -- fftw3.h not found") + message(STATUS "Looking for FFTW -- ${FFTW3_HEADER_TO_FIND} not found") endif() endif () @@ -335,52 +497,21 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR if(FFTW_LOOK_FOR_FFTW_SIMPLE) set(FFTW_PREC "f") set(FFTW_PREC_TESTFUNC "s") - elseif(FFTW_LOOK_FOR_FFTW_DOUBLE) - set(FFTW_PREC "") - set(FFTW_PREC_TESTFUNC "d") elseif(FFTW_LOOK_FOR_FFTW_LONG) set(FFTW_PREC "l") set(FFTW_PREC_TESTFUNC "l") elseif(FFTW_LOOK_FOR_FFTW_QUAD) set(FFTW_PREC "q") set(FFTW_PREC_TESTFUNC "q") + else() + set(FFTW_PREC "") + set(FFTW_PREC_TESTFUNC "d") endif() - if (FFTW_LOOK_FOR_MKL) - - set(FFTW_libs_to_find "mkl_intel_lp64;mkl_sequential;mkl_core") - - # Try to find the MKL fftw lib in the given paths - # ----------------------------------------------- - - # call cmake macro to find the lib path - if(FFTW_LIBDIR) - foreach(fftw_lib ${FFTW_libs_to_find}) - set(FFTW_${fftw_lib}_LIBRARY "FFTW_${fftw_lib}_LIBRARY-NOTFOUND") - find_library(FFTW_${fftw_lib}_LIBRARY - NAMES ${fftw_lib} - HINTS ${FFTW_LIBDIR}) - endforeach() - else() - if(FFTW_DIR) - foreach(fftw_lib ${FFTW_libs_to_find}) - set(FFTW_${fftw_lib}_LIBRARY "FFTW_${fftw_lib}_LIBRARY-NOTFOUND") - find_library(FFTW_${fftw_lib}_LIBRARY - NAMES ${fftw_lib} - HINTS ${FFTW_DIR} - PATH_SUFFIXES lib lib32 lib64) - endforeach() - else() - foreach(fftw_lib ${FFTW_libs_to_find}) - set(FFTW_${fftw_lib}_LIBRARY "FFTW_${fftw_lib}_LIBRARY-NOTFOUND") - find_library(FFTW_${fftw_lib}_LIBRARY - NAMES ${fftw_lib} - HINTS ${PATH_TO_LOOK_FOR}) - endforeach() - endif() - endif() + set(FFTW_LIBRARIES "") + set(FFTW_LIBRARY_DIRS "") - else(FFTW_LOOK_FOR_MKL) + if(NOT FFTW_LOOK_FOR_MKL) if (FFTW_LOOK_FOR_THREADS) set(FFTW_libs_to_find "fftw3${FFTW_PREC}_threads;fftw3${FFTW_PREC};fftw3") @@ -389,6 +520,15 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR else() set(FFTW_libs_to_find "fftw3${FFTW_PREC};fftw3") endif() + if (FFTW_LOOK_FOR_FFTW_QUAD) + if (NOT FFTW_LOOK_FOR_MKL AND NOT FFTW_LOOK_FOR_ESSL) + list(APPEND FFTW_libs_to_find "quadmath") + endif() + endif() + + if (FFTW_LOOK_FOR_ESSL) + set(FFTW_libs_to_find "fftw3_essl") + endif() # Try to find the fftw lib in the given paths # ---------------------------------------------- @@ -420,32 +560,123 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR endif() endif() - endif(FFTW_LOOK_FOR_MKL) + # If found, add path to cmake variable + # ------------------------------------ + foreach(fftw_lib ${FFTW_libs_to_find}) + + if (FFTW_${fftw_lib}_LIBRARY) + get_filename_component(${fftw_lib}_lib_path "${FFTW_${fftw_lib}_LIBRARY}" PATH) + # set cmake variables + list(APPEND FFTW_LIBRARIES "${FFTW_${fftw_lib}_LIBRARY}") + list(APPEND FFTW_LIBRARY_DIRS "${${fftw_lib}_lib_path}") + else () + list(APPEND FFTW_LIBRARIES "${FFTW_${fftw_lib}_LIBRARY}") + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Looking for FFTW -- lib ${fftw_lib} not found") + endif() + endif () + mark_as_advanced(FFTW_${fftw_lib}_LIBRARY) - # If found, add path to cmake variable - # ------------------------------------ - set(FFTW_LIBRARIES "") - set(FFTW_LIBRARY_DIRS "") - foreach(fftw_lib ${FFTW_libs_to_find}) - - if (FFTW_${fftw_lib}_LIBRARY) - get_filename_component(${fftw_lib}_lib_path "${FFTW_${fftw_lib}_LIBRARY}" PATH) - # set cmake variables - list(APPEND FFTW_LIBRARIES "${FFTW_${fftw_lib}_LIBRARY}") - list(APPEND FFTW_LIBRARY_DIRS "${${fftw_lib}_lib_path}") - else () - list(APPEND FFTW_LIBRARIES "${FFTW_${fftw_lib}_LIBRARY}") + endforeach() + + # check if one lib is NOTFOUND + foreach(lib ${FFTW_LIBRARIES}) + if (NOT lib) + set(FFTW_LIBRARIES "FFTW_LIBRARIES-NOTFOUND") + endif() + endforeach() + + endif(NOT FFTW_LOOK_FOR_MKL) + + if (FFTW_LOOK_FOR_MKL OR FFTW_LOOK_FOR_ESSL) + + # FFTW relies on blas libs + if (FFTW_LOOK_FOR_THREADS) + if (FFTW_LOOK_FOR_MKL) + if (BLAS_PAR_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${BLAS_PAR_LIBRARIES}") + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Multithreaded FFTW has been found: ${FFTW_LIBRARIES}") + endif() + else() + if (NOT FFTW_FIND_QUIETLY) + if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL) + message(FATAL_ERROR "FFTW is required but not found.") + else() + message(STATUS "Multithreaded FFTW not found.") + endif() + endif() + endif(BLAS_PAR_LIBRARIES) + elseif (FFTW_LOOK_FOR_ESSL) + if (FFTW_LIBRARIES AND BLAS_PAR_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${BLAS_PAR_LIBRARIES}") + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "Multithreaded FFTW has been found: ${FFTW_LIBRARIES}") + endif() + else() + if (NOT FFTW_FIND_QUIETLY) + if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL) + message(FATAL_ERROR "FFTW is required but not found.") + else() + message(STATUS "Multithreaded FFTW not found.") + endif() + endif() + endif(FFTW_LIBRARIES AND BLAS_PAR_LIBRARIES) + endif() + else(FFTW_LOOK_FOR_THREADS) + if (FFTW_LOOK_FOR_MKL) + if (BLAS_SEQ_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${BLAS_SEQ_LIBRARIES}") + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "FFTW has been found: ${FFTW_LIBRARIES}") + endif() + else() + if (NOT FFTW_FIND_QUIETLY) + if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL) + message(FATAL_ERROR "FFTW is required but not found.") + else() + message(STATUS "FFTW not found.") + endif() + endif() + endif(BLAS_SEQ_LIBRARIES) + elseif (FFTW_LOOK_FOR_ESSL) + if (FFTW_LIBRARIES AND BLAS_SEQ_LIBRARIES) + list(APPEND FFTW_LIBRARIES "${BLAS_SEQ_LIBRARIES}") + if (NOT FFTW_FIND_QUIETLY) + message(STATUS "FFTW has been found: ${FFTW_LIBRARIES}") + endif() + else() + if (NOT FFTW_FIND_QUIETLY) + if (FFTW_FIND_REQUIRED AND FFTW_FIND_REQUIRED_MKL) + message(FATAL_ERROR "FFTW is required but not found.") + else() + message(STATUS "FFTW not found.") + endif() + endif() + endif(FFTW_LIBRARIES AND BLAS_SEQ_LIBRARIES) + endif() + endif(FFTW_LOOK_FOR_THREADS) + + if (BLAS_LIBRARY_DIRS) + list(APPEND FFTW_LIBRARY_DIRS "${BLAS_LIBRARY_DIRS}") + else() if (NOT FFTW_FIND_QUIETLY) - message(STATUS "Looking for FFTW -- lib ${fftw_lib} not found") + message(WARNING "FFTW_LIBRARY_DIRS may not be complete because BLAS_LIBRARY_DIRS is empty.") endif() - endif () - mark_as_advanced(FFTW_${fftw_lib}_LIBRARY) + endif() - endforeach() + endif(FFTW_LOOK_FOR_MKL OR FFTW_LOOK_FOR_ESSL) list(REMOVE_DUPLICATES FFTW_INCLUDE_DIRS) list(REMOVE_DUPLICATES FFTW_LIBRARY_DIRS) + # check if one lib is NOTFOUND + foreach(lib ${FFTW_LIBRARIES}) + if (NOT lib) + set(FFTW_LIBRARIES "FFTW_LIBRARIES-NOTFOUND") + endif() + endforeach() + # check a function to validate the find if(FFTW_LIBRARIES) @@ -469,15 +700,15 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR endif() # OMP if(FFTW_LOOK_FOR_OMP) - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - # either gomp ... - #set(REQUIRED_FLAGS "-fopenmp") - #list(APPEND REQUIRED_LIBS "-lgomp") - # or iomp5 - list(APPEND REQUIRED_LIBS "-liomp5") - elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel") - list(APPEND REQUIRED_LIBS "-liomp5") - endif() + set(REQUIRED_FLAGS "-fopenmp") + #if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # # either gomp ... + # list(APPEND REQUIRED_LIBS "-lgomp") + # # or iomp5 + # list(APPEND REQUIRED_LIBS "-liomp5") + #elseif (CMAKE_C_COMPILER_ID STREQUAL "Intel") + # list(APPEND REQUIRED_LIBS "-liomp5") + #endif() endif() # MKL if(FFTW_LOOK_FOR_MKL) @@ -488,6 +719,7 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR endif() # m find_library(M_LIBRARY NAMES m) + mark_as_advanced(M_LIBRARY) if(M_LIBRARY) list(APPEND REQUIRED_LIBS "-lm") endif() @@ -506,7 +738,11 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR # test link unset(FFTW_WORKS CACHE) include(CheckFunctionExists) - check_function_exists(${FFTW_PREC_TESTFUNC}fftw_execute_ FFTW_WORKS) + if (FFTW_LOOK_FOR_ESSL) + check_function_exists(${FFTW_PREC_TESTFUNC}fftw_execute FFTW_WORKS) + else() + check_function_exists(${FFTW_PREC_TESTFUNC}fftw_execute_ FFTW_WORKS) + endif() mark_as_advanced(FFTW_WORKS) if(FFTW_WORKS) @@ -535,7 +771,12 @@ if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR set(CMAKE_REQUIRED_LIBRARIES) endif(FFTW_LIBRARIES) -endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR (FFTW_GIVEN_BY_USER) ) +endif( (NOT PKG_CONFIG_EXECUTABLE) OR + (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR + FFTW_GIVEN_BY_USER OR + FFTW_LOOK_FOR_MKL OR + FFTW_LOOK_FOR_ESSL + ) if (FFTW_LIBRARIES) list(GET FFTW_LIBRARIES 0 first_lib) @@ -547,11 +788,19 @@ if (FFTW_LIBRARIES) set(FFTW_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of FFTW library" FORCE) endif() endif() +mark_as_advanced(FFTW_DIR) +mark_as_advanced(FFTW_DIR_FOUND) # check that FFTW has been found # ------------------------------- include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(FFTW DEFAULT_MSG - FFTW_LIBRARIES - FFTW_INCLUDE_DIRS - FFTW_WORKS) +if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FFTW_FOUND) OR (FFTW_GIVEN_BY_USER) ) + find_package_handle_standard_args(FFTW DEFAULT_MSG + FFTW_LIBRARIES + FFTW_INCLUDE_DIRS + FFTW_WORKS) +else() + find_package_handle_standard_args(FFTW DEFAULT_MSG + FFTW_LIBRARIES + FFTW_WORKS) +endif() diff --git a/CMakeModules/morse/find/FindFXT.cmake b/CMakeModules/morse/find/FindFXT.cmake index 639da8b7b745cadcab65c62d6dfbf2a7cdd72e66..3fd9a6eb2d461ce3e86a7a515b570e30f98b6820 100644 --- a/CMakeModules/morse/find/FindFXT.cmake +++ b/CMakeModules/morse/find/FindFXT.cmake @@ -46,10 +46,10 @@ # License text for the above reference.) if (NOT FXT_FOUND) - set(FXT_DIR "" CACHE PATH "Installation directory of FXT library") - if (NOT FXT_FIND_QUIETLY) - message(STATUS "A cache variable, namely FXT_DIR, has been set to specify the install directory of FXT") - endif() + set(FXT_DIR "" CACHE PATH "Installation directory of FXT library") + if (NOT FXT_FIND_QUIETLY) + message(STATUS "A cache variable, namely FXT_DIR, has been set to specify the install directory of FXT") + endif() endif() set(ENV_FXT_DIR "$ENV{FXT_DIR}") @@ -57,7 +57,7 @@ set(ENV_FXT_INCDIR "$ENV{FXT_INCDIR}") set(ENV_FXT_LIBDIR "$ENV{FXT_LIBDIR}") set(FXT_GIVEN_BY_USER "FALSE") if ( FXT_DIR OR ( FXT_INCDIR AND FXT_LIBDIR) OR ENV_FXT_DIR OR (ENV_FXT_INCDIR AND ENV_FXT_LIBDIR) ) - set(FXT_GIVEN_BY_USER "TRUE") + set(FXT_GIVEN_BY_USER "TRUE") endif() # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) @@ -66,243 +66,245 @@ include(FindPkgConfig) find_package(PkgConfig QUIET) if(PKG_CONFIG_EXECUTABLE AND NOT FXT_GIVEN_BY_USER) - pkg_search_module(FXT fxt) - if (NOT FXT_FIND_QUIETLY) - if (FXT_FOUND AND FXT_LIBRARIES) - message(STATUS "Looking for FXT - found using PkgConfig") - #if(NOT FXT_INCLUDE_DIRS) - # message("${Magenta}FXT_INCLUDE_DIRS is empty using PkgConfig." - # "Perhaps the path to fxt headers is already present in your" - # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") - #endif() - else() - message("${Magenta}Looking for FXT - not found using PkgConfig." - "Perhaps you should add the directory containing fxt.pc to the" - "PKG_CONFIG_PATH environment variable.${ColourReset}") - endif() + pkg_search_module(FXT fxt) + if (NOT FXT_FIND_QUIETLY) + if (FXT_FOUND AND FXT_LIBRARIES) + message(STATUS "Looking for FXT - found using PkgConfig") + #if(NOT FXT_INCLUDE_DIRS) + # message("${Magenta}FXT_INCLUDE_DIRS is empty using PkgConfig." + # "Perhaps the path to fxt headers is already present in your" + # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") + #endif() + else() + message(STATUS "${Magenta}Looking for FXT - not found using PkgConfig." + "\n Perhaps you should add the directory containing fxt.pc to the" + "\n PKG_CONFIG_PATH environment variable.${ColourReset}") endif() + endif() endif(PKG_CONFIG_EXECUTABLE AND NOT FXT_GIVEN_BY_USER) if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FXT_FOUND) OR (FXT_GIVEN_BY_USER) ) - if (NOT FXT_FIND_QUIETLY) - message(STATUS "Looking for FXT - PkgConfig not used") - endif() + if (NOT FXT_FIND_QUIETLY) + message(STATUS "Looking for FXT - PkgConfig not used") + endif() - # Looking for include - # ------------------- + # Looking for include + # ------------------- - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - set(ENV_FXT_DIR "$ENV{FXT_DIR}") - set(ENV_FXT_INCDIR "$ENV{FXT_INCDIR}") - if(ENV_FXT_INCDIR) - list(APPEND _inc_env "${ENV_FXT_INCDIR}") - elseif(ENV_FXT_DIR) - list(APPEND _inc_env "${ENV_FXT_DIR}") - list(APPEND _inc_env "${ENV_FXT_DIR}/include") - list(APPEND _inc_env "${ENV_FXT_DIR}/include/fxt") + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + set(ENV_FXT_DIR "$ENV{FXT_DIR}") + set(ENV_FXT_INCDIR "$ENV{FXT_INCDIR}") + if(ENV_FXT_INCDIR) + list(APPEND _inc_env "${ENV_FXT_INCDIR}") + elseif(ENV_FXT_DIR) + list(APPEND _inc_env "${ENV_FXT_DIR}") + list(APPEND _inc_env "${ENV_FXT_DIR}/include") + list(APPEND _inc_env "${ENV_FXT_DIR}/include/fxt") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) - # Try to find the fxt header in the given paths - # ------------------------------------------------- - # call cmake macro to find the header path - if(FXT_INCDIR) - set(FXT_fxt.h_DIRS "FXT_fxt.h_DIRS-NOTFOUND") - find_path(FXT_fxt.h_DIRS - NAMES fxt.h - HINTS ${FXT_INCDIR}) + # Try to find the fxt header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(FXT_INCDIR) + set(FXT_fxt.h_DIRS "FXT_fxt.h_DIRS-NOTFOUND") + find_path(FXT_fxt.h_DIRS + NAMES fxt.h + HINTS ${FXT_INCDIR}) + else() + if(FXT_DIR) + set(FXT_fxt.h_DIRS "FXT_fxt.h_DIRS-NOTFOUND") + find_path(FXT_fxt.h_DIRS + NAMES fxt.h + HINTS ${FXT_DIR} + PATH_SUFFIXES "include" "include/fxt") else() - if(FXT_DIR) - set(FXT_fxt.h_DIRS "FXT_fxt.h_DIRS-NOTFOUND") - find_path(FXT_fxt.h_DIRS - NAMES fxt.h - HINTS ${FXT_DIR} - PATH_SUFFIXES "include" "include/fxt") - else() - set(FXT_fxt.h_DIRS "FXT_fxt.h_DIRS-NOTFOUND") - find_path(FXT_fxt.h_DIRS - NAMES fxt.h - HINTS ${_inc_env} - PATH_SUFFIXES "fxt") - endif() + set(FXT_fxt.h_DIRS "FXT_fxt.h_DIRS-NOTFOUND") + find_path(FXT_fxt.h_DIRS + NAMES fxt.h + HINTS ${_inc_env} + PATH_SUFFIXES "fxt") endif() - mark_as_advanced(FXT_fxt.h_DIRS) + endif() + mark_as_advanced(FXT_fxt.h_DIRS) - # Add path to cmake variable - # ------------------------------------ - if (FXT_fxt.h_DIRS) - set(FXT_INCLUDE_DIRS "${FXT_fxt.h_DIRS}") - else () - set(FXT_INCLUDE_DIRS "FXT_INCLUDE_DIRS-NOTFOUND") - if(NOT FXT_FIND_QUIETLY) - message(STATUS "Looking for fxt -- fxt.h not found") - endif() - endif () + # Add path to cmake variable + # ------------------------------------ + if (FXT_fxt.h_DIRS) + set(FXT_INCLUDE_DIRS "${FXT_fxt.h_DIRS}") + else () + set(FXT_INCLUDE_DIRS "FXT_INCLUDE_DIRS-NOTFOUND") + if(NOT FXT_FIND_QUIETLY) + message(STATUS "Looking for fxt -- fxt.h not found") + endif() + endif () - if (FXT_INCLUDE_DIRS) - list(REMOVE_DUPLICATES FXT_INCLUDE_DIRS) - endif () + if (FXT_INCLUDE_DIRS) + list(REMOVE_DUPLICATES FXT_INCLUDE_DIRS) + endif () - # Looking for lib - # --------------- + # Looking for lib + # --------------- - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - set(ENV_FXT_LIBDIR "$ENV{FXT_LIBDIR}") - if(ENV_FXT_LIBDIR) - list(APPEND _lib_env "${ENV_FXT_LIBDIR}") - elseif(ENV_FXT_DIR) - list(APPEND _lib_env "${ENV_FXT_DIR}") - list(APPEND _lib_env "${ENV_FXT_DIR}/lib") + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_FXT_LIBDIR "$ENV{FXT_LIBDIR}") + if(ENV_FXT_LIBDIR) + list(APPEND _lib_env "${ENV_FXT_LIBDIR}") + elseif(ENV_FXT_DIR) + list(APPEND _lib_env "${ENV_FXT_DIR}") + list(APPEND _lib_env "${ENV_FXT_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") endif() - list(REMOVE_DUPLICATES _lib_env) + endif() + list(REMOVE_DUPLICATES _lib_env) - # Try to find the fxt lib in the given paths - # ---------------------------------------------- + # Try to find the fxt lib in the given paths + # ---------------------------------------------- - # call cmake macro to find the lib path - if(FXT_LIBDIR) - set(FXT_fxt_LIBRARY "FXT_fxt_LIBRARY-NOTFOUND") - find_library(FXT_fxt_LIBRARY - NAMES fxt - HINTS ${FXT_LIBDIR}) + # call cmake macro to find the lib path + if(FXT_LIBDIR) + set(FXT_fxt_LIBRARY "FXT_fxt_LIBRARY-NOTFOUND") + find_library(FXT_fxt_LIBRARY + NAMES fxt + HINTS ${FXT_LIBDIR}) + else() + if(FXT_DIR) + set(FXT_fxt_LIBRARY "FXT_fxt_LIBRARY-NOTFOUND") + find_library(FXT_fxt_LIBRARY + NAMES fxt + HINTS ${FXT_DIR} + PATH_SUFFIXES lib lib32 lib64) else() - if(FXT_DIR) - set(FXT_fxt_LIBRARY "FXT_fxt_LIBRARY-NOTFOUND") - find_library(FXT_fxt_LIBRARY - NAMES fxt - HINTS ${FXT_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(FXT_fxt_LIBRARY "FXT_fxt_LIBRARY-NOTFOUND") - find_library(FXT_fxt_LIBRARY - NAMES fxt - HINTS ${_lib_env}) - endif() + set(FXT_fxt_LIBRARY "FXT_fxt_LIBRARY-NOTFOUND") + find_library(FXT_fxt_LIBRARY + NAMES fxt + HINTS ${_lib_env}) endif() - mark_as_advanced(FXT_fxt_LIBRARY) + endif() + mark_as_advanced(FXT_fxt_LIBRARY) - # If found, add path to cmake variable - # ------------------------------------ - if (FXT_fxt_LIBRARY) - get_filename_component(fxt_lib_path ${FXT_fxt_LIBRARY} PATH) - # set cmake variables (respects naming convention) - set(FXT_LIBRARIES "${FXT_fxt_LIBRARY}") - set(FXT_LIBRARY_DIRS "${fxt_lib_path}") - else () - set(FXT_LIBRARIES "FXT_LIBRARIES-NOTFOUND") - set(FXT_LIBRARY_DIRS "FXT_LIBRARY_DIRS-NOTFOUND") - if(NOT FXT_FIND_QUIETLY) - message(STATUS "Looking for fxt -- lib fxt not found") - endif() - endif () + # If found, add path to cmake variable + # ------------------------------------ + if (FXT_fxt_LIBRARY) + get_filename_component(fxt_lib_path ${FXT_fxt_LIBRARY} PATH) + # set cmake variables (respects naming convention) + set(FXT_LIBRARIES "${FXT_fxt_LIBRARY}") + set(FXT_LIBRARY_DIRS "${fxt_lib_path}") + else () + set(FXT_LIBRARIES "FXT_LIBRARIES-NOTFOUND") + set(FXT_LIBRARY_DIRS "FXT_LIBRARY_DIRS-NOTFOUND") + if(NOT FXT_FIND_QUIETLY) + message(STATUS "Looking for fxt -- lib fxt not found") + endif() + endif () - if (FXT_LIBRARY_DIRS) - list(REMOVE_DUPLICATES FXT_LIBRARY_DIRS) - endif () + if (FXT_LIBRARY_DIRS) + list(REMOVE_DUPLICATES FXT_LIBRARY_DIRS) + endif () - # check a function to validate the find - if(FXT_LIBRARIES) + # check a function to validate the find + if(FXT_LIBRARIES) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) - # FXT - if (FXT_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${FXT_INCLUDE_DIRS}") - endif() - if (FXT_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${FXT_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${FXT_LIBRARIES}") + # FXT + if (FXT_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${FXT_INCLUDE_DIRS}") + endif() + if (FXT_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${FXT_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${FXT_LIBRARIES}") - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - # test link - unset(FXT_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(fut_keychange FXT_WORKS) - mark_as_advanced(FXT_WORKS) + # test link + unset(FXT_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(fut_keychange FXT_WORKS) + mark_as_advanced(FXT_WORKS) - if(NOT FXT_WORKS) - if(NOT FXT_FIND_QUIETLY) - message(STATUS "Looking for fxt : test of fut_keychange with fxt library fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(FXT_LIBRARIES) + if(NOT FXT_WORKS) + if(NOT FXT_FIND_QUIETLY) + message(STATUS "Looking for fxt : test of fut_keychange with fxt library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(FXT_LIBRARIES) endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT FXT_FOUND) OR (FXT_GIVEN_BY_USER) ) if (FXT_LIBRARIES) - if (FXT_LIBRARY_DIRS) - list(GET FXT_LIBRARY_DIRS 0 first_lib_path) - else() - list(GET FXT_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - endif() - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(FXT_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of FXT library" FORCE) - else() - set(FXT_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of FXT library" FORCE) - endif() + if (FXT_LIBRARY_DIRS) + list(GET FXT_LIBRARY_DIRS 0 first_lib_path) + else() + list(GET FXT_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(FXT_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of FXT library" FORCE) + else() + set(FXT_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of FXT library" FORCE) + endif() endif() +mark_as_advanced(FXT_DIR) +mark_as_advanced(FXT_DIR_FOUND) # check that FXT has been found # ------------------------------- include(FindPackageHandleStandardArgs) if (PKG_CONFIG_EXECUTABLE AND FXT_FOUND) - find_package_handle_standard_args(FXT DEFAULT_MSG - FXT_LIBRARIES) + find_package_handle_standard_args(FXT DEFAULT_MSG + FXT_LIBRARIES) else() - find_package_handle_standard_args(FXT DEFAULT_MSG - FXT_LIBRARIES - FXT_WORKS) + find_package_handle_standard_args(FXT DEFAULT_MSG + FXT_LIBRARIES + FXT_WORKS) endif() diff --git a/CMakeModules/morse/find/FindHWLOC.cmake b/CMakeModules/morse/find/FindHWLOC.cmake index 7f640fabc6138f5fa12f62aea2fe20d4345a6dd1..a831b5c725acc0b88dfba169e3ed477dd5bf2910 100644 --- a/CMakeModules/morse/find/FindHWLOC.cmake +++ b/CMakeModules/morse/find/FindHWLOC.cmake @@ -49,10 +49,10 @@ include(CheckStructHasMember) include(CheckCSourceCompiles) if (NOT HWLOC_FOUND) - set(HWLOC_DIR "" CACHE PATH "Installation directory of HWLOC library") - if (NOT HWLOC_FIND_QUIETLY) - message(STATUS "A cache variable, namely HWLOC_DIR, has been set to specify the install directory of HWLOC") - endif() + set(HWLOC_DIR "" CACHE PATH "Installation directory of HWLOC library") + if (NOT HWLOC_FIND_QUIETLY) + message(STATUS "A cache variable, namely HWLOC_DIR, has been set to specify the install directory of HWLOC") + endif() endif() set(ENV_HWLOC_DIR "$ENV{HWLOC_DIR}") @@ -60,7 +60,7 @@ set(ENV_HWLOC_INCDIR "$ENV{HWLOC_INCDIR}") set(ENV_HWLOC_LIBDIR "$ENV{HWLOC_LIBDIR}") set(HWLOC_GIVEN_BY_USER "FALSE") if ( HWLOC_DIR OR ( HWLOC_INCDIR AND HWLOC_LIBDIR) OR ENV_HWLOC_DIR OR (ENV_HWLOC_INCDIR AND ENV_HWLOC_LIBDIR) ) - set(HWLOC_GIVEN_BY_USER "TRUE") + set(HWLOC_GIVEN_BY_USER "TRUE") endif() # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) @@ -69,261 +69,263 @@ include(FindPkgConfig) find_package(PkgConfig QUIET) if( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER ) - pkg_search_module(HWLOC hwloc) - if (NOT HWLOC_FIND_QUIETLY) - if (HWLOC_FOUND AND HWLOC_LIBRARIES) - message(STATUS "Looking for HWLOC - found using PkgConfig") - #if(NOT HWLOC_INCLUDE_DIRS) - # message("${Magenta}HWLOC_INCLUDE_DIRS is empty using PkgConfig." - # "Perhaps the path to hwloc headers is already present in your" - # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") - #endif() - else() - message("${Magenta}Looking for HWLOC - not found using PkgConfig." - "Perhaps you should add the directory containing hwloc.pc to" - "the PKG_CONFIG_PATH environment variable.${ColourReset}") - endif() + pkg_search_module(HWLOC hwloc) + if (NOT HWLOC_FIND_QUIETLY) + if (HWLOC_FOUND AND HWLOC_LIBRARIES) + message(STATUS "Looking for HWLOC - found using PkgConfig") + #if(NOT HWLOC_INCLUDE_DIRS) + # message("${Magenta}HWLOC_INCLUDE_DIRS is empty using PkgConfig." + # "Perhaps the path to hwloc headers is already present in your" + # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") + #endif() + else() + message(STATUS "${Magenta}Looking for HWLOC - not found using PkgConfig." + "\n Perhaps you should add the directory containing hwloc.pc to" + "\n the PKG_CONFIG_PATH environment variable.${ColourReset}") endif() + endif() endif( PKG_CONFIG_EXECUTABLE AND NOT HWLOC_GIVEN_BY_USER ) if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT HWLOC_FOUND) OR (HWLOC_GIVEN_BY_USER) ) - if (NOT HWLOC_FIND_QUIETLY) - message(STATUS "Looking for HWLOC - PkgConfig not used") + if (NOT HWLOC_FIND_QUIETLY) + message(STATUS "Looking for HWLOC - PkgConfig not used") + endif() + + # Looking for include + # ------------------- + + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + if(ENV_HWLOC_INCDIR) + list(APPEND _inc_env "${ENV_HWLOC_INCDIR}") + elseif(ENV_HWLOC_DIR) + list(APPEND _inc_env "${ENV_HWLOC_DIR}") + list(APPEND _inc_env "${ENV_HWLOC_DIR}/include") + list(APPEND _inc_env "${ENV_HWLOC_DIR}/include/hwloc") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") endif() - - # Looking for include - # ------------------- - - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - if(ENV_HWLOC_INCDIR) - list(APPEND _inc_env "${ENV_HWLOC_INCDIR}") - elseif(ENV_HWLOC_DIR) - list(APPEND _inc_env "${ENV_HWLOC_DIR}") - list(APPEND _inc_env "${ENV_HWLOC_DIR}/include") - list(APPEND _inc_env "${ENV_HWLOC_DIR}/include/hwloc") + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) + + # set paths where to look for + set(PATH_TO_LOOK_FOR "${_inc_env}") + + # Try to find the hwloc header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(HWLOC_INCDIR) + set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND") + find_path(HWLOC_hwloc.h_DIRS + NAMES hwloc.h + HINTS ${HWLOC_INCDIR}) + else() + if(HWLOC_DIR) + set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND") + find_path(HWLOC_hwloc.h_DIRS + NAMES hwloc.h + HINTS ${HWLOC_DIR} + PATH_SUFFIXES "include" "include/hwloc") else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND") + find_path(HWLOC_hwloc.h_DIRS + NAMES hwloc.h + HINTS ${PATH_TO_LOOK_FOR} + PATH_SUFFIXES "hwloc") endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) - - # set paths where to look for - set(PATH_TO_LOOK_FOR "${_inc_env}") - - # Try to find the hwloc header in the given paths - # ------------------------------------------------- - # call cmake macro to find the header path - if(HWLOC_INCDIR) - set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND") - find_path(HWLOC_hwloc.h_DIRS - NAMES hwloc.h - HINTS ${HWLOC_INCDIR}) + endif() + mark_as_advanced(HWLOC_hwloc.h_DIRS) + + # Add path to cmake variable + # ------------------------------------ + if (HWLOC_hwloc.h_DIRS) + set(HWLOC_INCLUDE_DIRS "${HWLOC_hwloc.h_DIRS}") + else () + set(HWLOC_INCLUDE_DIRS "HWLOC_INCLUDE_DIRS-NOTFOUND") + if(NOT HWLOC_FIND_QUIETLY) + message(STATUS "Looking for hwloc -- hwloc.h not found") + endif() + endif () + + if (HWLOC_INCLUDE_DIRS) + list(REMOVE_DUPLICATES HWLOC_INCLUDE_DIRS) + endif () + + + # Looking for lib + # --------------- + + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + if(ENV_HWLOC_LIBDIR) + list(APPEND _lib_env "${ENV_HWLOC_LIBDIR}") + elseif(ENV_HWLOC_DIR) + list(APPEND _lib_env "${ENV_HWLOC_DIR}") + list(APPEND _lib_env "${ENV_HWLOC_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") else() - if(HWLOC_DIR) - set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND") - find_path(HWLOC_hwloc.h_DIRS - NAMES hwloc.h - HINTS ${HWLOC_DIR} - PATH_SUFFIXES "include" "include/hwloc") - else() - set(HWLOC_hwloc.h_DIRS "HWLOC_hwloc.h_DIRS-NOTFOUND") - find_path(HWLOC_hwloc.h_DIRS - NAMES hwloc.h - HINTS ${PATH_TO_LOOK_FOR} - PATH_SUFFIXES "hwloc") - endif() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") endif() - mark_as_advanced(HWLOC_hwloc.h_DIRS) - - # Add path to cmake variable - # ------------------------------------ - if (HWLOC_hwloc.h_DIRS) - set(HWLOC_INCLUDE_DIRS "${HWLOC_hwloc.h_DIRS}") - else () - set(HWLOC_INCLUDE_DIRS "HWLOC_INCLUDE_DIRS-NOTFOUND") - if(NOT HWLOC_FIND_QUIETLY) - message(STATUS "Looking for hwloc -- hwloc.h not found") - endif() - endif () - - if (HWLOC_INCLUDE_DIRS) - list(REMOVE_DUPLICATES HWLOC_INCLUDE_DIRS) - endif () - - - # Looking for lib - # --------------- - - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - if(ENV_HWLOC_LIBDIR) - list(APPEND _lib_env "${ENV_HWLOC_LIBDIR}") - elseif(ENV_HWLOC_DIR) - list(APPEND _lib_env "${ENV_HWLOC_DIR}") - list(APPEND _lib_env "${ENV_HWLOC_DIR}/lib") + endif() + list(REMOVE_DUPLICATES _lib_env) + + # set paths where to look for + set(PATH_TO_LOOK_FOR "${_lib_env}") + + # Try to find the hwloc lib in the given paths + # ---------------------------------------------- + + # call cmake macro to find the lib path + if(HWLOC_LIBDIR) + set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND") + find_library(HWLOC_hwloc_LIBRARY + NAMES hwloc + HINTS ${HWLOC_LIBDIR}) + else() + if(HWLOC_DIR) + set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND") + find_library(HWLOC_hwloc_LIBRARY + NAMES hwloc + HINTS ${HWLOC_DIR} + PATH_SUFFIXES lib lib32 lib64) else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() + set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND") + find_library(HWLOC_hwloc_LIBRARY + NAMES hwloc + HINTS ${PATH_TO_LOOK_FOR}) endif() - list(REMOVE_DUPLICATES _lib_env) + endif() + mark_as_advanced(HWLOC_hwloc_LIBRARY) + + # If found, add path to cmake variable + # ------------------------------------ + if (HWLOC_hwloc_LIBRARY) + get_filename_component(hwloc_lib_path ${HWLOC_hwloc_LIBRARY} PATH) + # set cmake variables (respects naming convention) + set(HWLOC_LIBRARIES "${HWLOC_hwloc_LIBRARY}") + set(HWLOC_LIBRARY_DIRS "${hwloc_lib_path}") + else () + set(HWLOC_LIBRARIES "HWLOC_LIBRARIES-NOTFOUND") + set(HWLOC_LIBRARY_DIRS "HWLOC_LIBRARY_DIRS-NOTFOUND") + if(NOT HWLOC_FIND_QUIETLY) + message(STATUS "Looking for hwloc -- lib hwloc not found") + endif() + endif () - # set paths where to look for - set(PATH_TO_LOOK_FOR "${_lib_env}") + if (HWLOC_LIBRARY_DIRS) + list(REMOVE_DUPLICATES HWLOC_LIBRARY_DIRS) + endif () - # Try to find the hwloc lib in the given paths - # ---------------------------------------------- + # check a function to validate the find + if(HWLOC_LIBRARIES) - # call cmake macro to find the lib path - if(HWLOC_LIBDIR) - set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND") - find_library(HWLOC_hwloc_LIBRARY - NAMES hwloc - HINTS ${HWLOC_LIBDIR}) - else() - if(HWLOC_DIR) - set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND") - find_library(HWLOC_hwloc_LIBRARY - NAMES hwloc - HINTS ${HWLOC_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(HWLOC_hwloc_LIBRARY "HWLOC_hwloc_LIBRARY-NOTFOUND") - find_library(HWLOC_hwloc_LIBRARY - NAMES hwloc - HINTS ${PATH_TO_LOOK_FOR}) - endif() - endif() - mark_as_advanced(HWLOC_hwloc_LIBRARY) - - # If found, add path to cmake variable - # ------------------------------------ - if (HWLOC_hwloc_LIBRARY) - get_filename_component(hwloc_lib_path ${HWLOC_hwloc_LIBRARY} PATH) - # set cmake variables (respects naming convention) - set(HWLOC_LIBRARIES "${HWLOC_hwloc_LIBRARY}") - set(HWLOC_LIBRARY_DIRS "${hwloc_lib_path}") - else () - set(HWLOC_LIBRARIES "HWLOC_LIBRARIES-NOTFOUND") - set(HWLOC_LIBRARY_DIRS "HWLOC_LIBRARY_DIRS-NOTFOUND") - if(NOT HWLOC_FIND_QUIETLY) - message(STATUS "Looking for hwloc -- lib hwloc not found") - endif() - endif () + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + # HWLOC + if (HWLOC_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}") + endif() if (HWLOC_LIBRARY_DIRS) - list(REMOVE_DUPLICATES HWLOC_LIBRARY_DIRS) - endif () - - # check a function to validate the find - if(HWLOC_LIBRARIES) - - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) - - # HWLOC - if (HWLOC_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${HWLOC_INCLUDE_DIRS}") - endif() - if (HWLOC_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${HWLOC_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${HWLOC_LIBRARIES}") - - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - - # test link - unset(HWLOC_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(hwloc_topology_init HWLOC_WORKS) - mark_as_advanced(HWLOC_WORKS) - - if(NOT HWLOC_WORKS) - if(NOT HWLOC_FIND_QUIETLY) - message(STATUS "Looking for hwloc : test of hwloc_topology_init with hwloc library fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(HWLOC_LIBRARIES) + set(REQUIRED_LIBDIRS "${HWLOC_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${HWLOC_LIBRARIES}") + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(HWLOC_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(hwloc_topology_init HWLOC_WORKS) + mark_as_advanced(HWLOC_WORKS) + + if(NOT HWLOC_WORKS) + if(NOT HWLOC_FIND_QUIETLY) + message(STATUS "Looking for hwloc : test of hwloc_topology_init with hwloc library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(HWLOC_LIBRARIES) endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT HWLOC_FOUND) OR (HWLOC_GIVEN_BY_USER) ) if (HWLOC_LIBRARIES) - if (HWLOC_LIBRARY_DIRS) - list(GET HWLOC_LIBRARY_DIRS 0 first_lib_path) - else() - list(GET HWLOC_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - endif() - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(HWLOC_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of HWLOC library" FORCE) - else() - set(HWLOC_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of HWLOC library" FORCE) - endif() + if (HWLOC_LIBRARY_DIRS) + list(GET HWLOC_LIBRARY_DIRS 0 first_lib_path) + else() + list(GET HWLOC_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(HWLOC_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of HWLOC library" FORCE) + else() + set(HWLOC_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of HWLOC library" FORCE) + endif() endif() +mark_as_advanced(HWLOC_DIR) +mark_as_advanced(HWLOC_DIR_FOUND) # check that HWLOC has been found # ------------------------------- include(FindPackageHandleStandardArgs) if (PKG_CONFIG_EXECUTABLE AND HWLOC_FOUND) - find_package_handle_standard_args(HWLOC DEFAULT_MSG - HWLOC_LIBRARIES) + find_package_handle_standard_args(HWLOC DEFAULT_MSG + HWLOC_LIBRARIES) else() - find_package_handle_standard_args(HWLOC DEFAULT_MSG - HWLOC_LIBRARIES - HWLOC_WORKS) + find_package_handle_standard_args(HWLOC DEFAULT_MSG + HWLOC_LIBRARIES + HWLOC_WORKS) endif() if (HWLOC_FOUND) - set(HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES}) - list(APPEND CMAKE_REQUIRED_INCLUDES ${HWLOC_INCLUDE_DIRS}) - - # test headers to guess the version - check_struct_has_member( "struct hwloc_obj" parent hwloc.h HAVE_HWLOC_PARENT_MEMBER ) - check_struct_has_member( "struct hwloc_cache_attr_s" size hwloc.h HAVE_HWLOC_CACHE_ATTR ) - check_c_source_compiles( "#include - int main(void) { hwloc_obj_t o; o->type = HWLOC_OBJ_PU; return 0;}" HAVE_HWLOC_OBJ_PU) - check_library_exists(${HWLOC_LIBRARIES} hwloc_bitmap_free "" HAVE_HWLOC_BITMAP) - - set(CMAKE_REQUIRED_INCLUDES ${HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES}) + set(HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES}) + list(APPEND CMAKE_REQUIRED_INCLUDES ${HWLOC_INCLUDE_DIRS}) + + # test headers to guess the version + check_struct_has_member( "struct hwloc_obj" parent hwloc.h HAVE_HWLOC_PARENT_MEMBER ) + check_struct_has_member( "struct hwloc_cache_attr_s" size hwloc.h HAVE_HWLOC_CACHE_ATTR ) + check_c_source_compiles( "#include + int main(void) { hwloc_obj_t o; o->type = HWLOC_OBJ_PU; return 0;}" HAVE_HWLOC_OBJ_PU) + include(CheckLibraryExists) + check_library_exists(${HWLOC_LIBRARIES} hwloc_bitmap_free "" HAVE_HWLOC_BITMAP) + + set(CMAKE_REQUIRED_INCLUDES ${HWLOC_SAVE_CMAKE_REQUIRED_INCLUDES}) endif() - diff --git a/CMakeModules/morse/find/FindHYPRE.cmake b/CMakeModules/morse/find/FindHYPRE.cmake new file mode 100644 index 0000000000000000000000000000000000000000..944b5ecbdb952d13a4b2e0bee15352cda500bc52 --- /dev/null +++ b/CMakeModules/morse/find/FindHYPRE.cmake @@ -0,0 +1,273 @@ +### +# +# @copyright (c) 2009-2014 The University of Tennessee and The University +# of Tennessee Research Foundation. +# All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. +# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. +# +### +# +# - Find HYPRE include dirs and libraries +# Use this module by invoking find_package with the form: +# find_package(HYPRE +# [REQUIRED]) # Fail with error if hypre is not found +# +# This module finds headers and hypre library. +# Results are reported in variables: +# HYPRE_FOUND - True if headers and requested libraries were found +# HYPRE_INCLUDE_DIRS - hypre include directories +# HYPRE_LIBRARY_DIRS - Link directories for hypre libraries +# HYPRE_LIBRARIES - hypre component libraries to be linked +# +# The user can give specific paths where to find the libraries adding cmake +# options at configure (ex: cmake path/to/project -DHYPRE_DIR=path/to/hypre): +# HYPRE_DIR - Where to find the base directory of hypre +# HYPRE_INCDIR - Where to find the header files +# HYPRE_LIBDIR - Where to find the library files +# The module can also look for the following environment variables if paths +# are not given as cmake variable: HYPRE_DIR, HYPRE_INCDIR, HYPRE_LIBDIR + +#============================================================================= +# Copyright 2016 Inria +# Copyright 2016 Florent Pruvost +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file MORSE-Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of Morse, substitute the full +# License text for the above reference.) + +if (NOT HYPRE_FOUND) + set(HYPRE_DIR "" CACHE PATH "Installation directory of HYPRE library") + if (NOT HYPRE_FIND_QUIETLY) + message(STATUS "A cache variable, namely HYPRE_DIR, has been set to specify the install directory of HYPRE") + endif() +endif() + +set(ENV_HYPRE_DIR "$ENV{HYPRE_DIR}") +set(ENV_HYPRE_INCDIR "$ENV{HYPRE_INCDIR}") +set(ENV_HYPRE_LIBDIR "$ENV{HYPRE_LIBDIR}") +set(HYPRE_GIVEN_BY_USER "FALSE") +if ( HYPRE_DIR OR ( HYPRE_INCDIR AND HYPRE_LIBDIR) OR ENV_HYPRE_DIR OR (ENV_HYPRE_INCDIR AND ENV_HYPRE_LIBDIR) ) + set(HYPRE_GIVEN_BY_USER "TRUE") +endif() + +# Looking for include +# ------------------- + +# Add system include paths to search include +# ------------------------------------------ +unset(_inc_env) +if(ENV_HYPRE_INCDIR) + list(APPEND _inc_env "${ENV_HYPRE_INCDIR}") +elseif(ENV_HYPRE_DIR) + list(APPEND _inc_env "${ENV_HYPRE_DIR}") + list(APPEND _inc_env "${ENV_HYPRE_DIR}/include") + list(APPEND _inc_env "${ENV_HYPRE_DIR}/include/hypre") +else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() +endif() +list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") +list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") +list(REMOVE_DUPLICATES _inc_env) + +# set paths where to look for +set(PATH_TO_LOOK_FOR "${_inc_env}") + +# Try to find the hypre header in the given paths +# ------------------------------------------------- +# call cmake macro to find the header path +if(HYPRE_INCDIR) + set(HYPRE_HYPRE.h_DIRS "HYPRE_HYPRE.h_DIRS-NOTFOUND") + find_path(HYPRE_HYPRE.h_DIRS + NAMES HYPRE.h + HINTS ${HYPRE_INCDIR}) +else() + if(HYPRE_DIR) + set(HYPRE_HYPRE.h_DIRS "HYPRE_HYPRE.h_DIRS-NOTFOUND") + find_path(HYPRE_HYPRE.h_DIRS + NAMES HYPRE.h + HINTS ${HYPRE_DIR} + PATH_SUFFIXES "include" "include/hypre") + else() + set(HYPRE_HYPRE.h_DIRS "HYPRE_HYPRE.h_DIRS-NOTFOUND") + find_path(HYPRE_HYPRE.h_DIRS + NAMES HYPRE.h + HINTS ${PATH_TO_LOOK_FOR} + PATH_SUFFIXES "hypre") + endif() +endif() +mark_as_advanced(HYPRE_HYPRE.h_DIRS) + +# Add path to cmake variable +# ------------------------------------ +if (HYPRE_HYPRE.h_DIRS) + set(HYPRE_INCLUDE_DIRS "${HYPRE_HYPRE.h_DIRS}") +else () + set(HYPRE_INCLUDE_DIRS "HYPRE_INCLUDE_DIRS-NOTFOUND") + if(NOT HYPRE_FIND_QUIETLY) + message(STATUS "Looking for hypre -- HYPRE.h not found") + endif() +endif () + +if (HYPRE_INCLUDE_DIRS) + list(REMOVE_DUPLICATES HYPRE_INCLUDE_DIRS) +endif () + + +# Looking for lib +# --------------- + +# Add system library paths to search lib +# -------------------------------------- +unset(_lib_env) +if(ENV_HYPRE_LIBDIR) + list(APPEND _lib_env "${ENV_HYPRE_LIBDIR}") +elseif(ENV_HYPRE_DIR) + list(APPEND _lib_env "${ENV_HYPRE_DIR}") + list(APPEND _lib_env "${ENV_HYPRE_DIR}/lib") +else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() +endif() +list(REMOVE_DUPLICATES _lib_env) + +# set paths where to look for +set(PATH_TO_LOOK_FOR "${_lib_env}") + +# Try to find the hypre lib in the given paths +# ---------------------------------------------- + +# call cmake macro to find the lib path +if(HYPRE_LIBDIR) + set(HYPRE_HYPRE_LIBRARY "HYPRE_HYPRE_LIBRARY-NOTFOUND") + find_library(HYPRE_HYPRE_LIBRARY + NAMES HYPRE + HINTS ${HYPRE_LIBDIR}) +else() + if(HYPRE_DIR) + set(HYPRE_HYPRE_LIBRARY "HYPRE_HYPRE_LIBRARY-NOTFOUND") + find_library(HYPRE_HYPRE_LIBRARY + NAMES HYPRE + HINTS ${HYPRE_DIR} + PATH_SUFFIXES lib lib32 lib64) + else() + set(HYPRE_HYPRE_LIBRARY "HYPRE_HYPRE_LIBRARY-NOTFOUND") + find_library(HYPRE_HYPRE_LIBRARY + NAMES HYPRE + HINTS ${PATH_TO_LOOK_FOR}) + endif() +endif() +mark_as_advanced(HYPRE_HYPRE_LIBRARY) + +# If found, add path to cmake variable +# ------------------------------------ +if (HYPRE_HYPRE_LIBRARY) + get_filename_component(hypre_lib_path ${HYPRE_HYPRE_LIBRARY} PATH) + # set cmake variables (respects naming convention) + set(HYPRE_LIBRARIES "${HYPRE_HYPRE_LIBRARY}") + set(HYPRE_LIBRARY_DIRS "${hypre_lib_path}") +else () + set(HYPRE_LIBRARIES "HYPRE_LIBRARIES-NOTFOUND") + set(HYPRE_LIBRARY_DIRS "HYPRE_LIBRARY_DIRS-NOTFOUND") + if(NOT HYPRE_FIND_QUIETLY) + message(STATUS "Looking for hypre -- lib HYPRE not found") + endif() +endif () + +if (HYPRE_LIBRARY_DIRS) + list(REMOVE_DUPLICATES HYPRE_LIBRARY_DIRS) +endif () + +# check a function to validate the find +if(HYPRE_LIBRARIES) + + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # HYPRE + if (HYPRE_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${HYPRE_INCLUDE_DIRS}") + endif() + if (HYPRE_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${HYPRE_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${HYPRE_LIBRARIES}") + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(HYPRE_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(HYPRE_StructGridCreate HYPRE_WORKS) + mark_as_advanced(HYPRE_WORKS) + + if(NOT HYPRE_WORKS) + if(NOT HYPRE_FIND_QUIETLY) + message(STATUS "Looking for HYPRE : test of HYPRE_StructGridCreate with HYPRE library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) +endif(HYPRE_LIBRARIES) + +if (HYPRE_LIBRARIES) + if (HYPRE_LIBRARY_DIRS) + list(GET HYPRE_LIBRARY_DIRS 0 first_lib_path) + else() + list(GET HYPRE_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(HYPRE_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of HYPRE library" FORCE) + else() + set(HYPRE_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of HYPRE library" FORCE) + endif() +endif() +mark_as_advanced(HYPRE_DIR) +mark_as_advanced(HYPRE_DIR_FOUND) + +# check that HYPRE has been found +# ------------------------------- +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(HYPRE DEFAULT_MSG + HYPRE_LIBRARIES + HYPRE_WORKS) diff --git a/CMakeModules/morse/find/FindLAPACK.cmake b/CMakeModules/morse/find/FindLAPACK.cmake index 81e3869f731bc7c096a17b2d8749ad64a2332a50..378a8fdb81c63b518bb11a7c29832b201a116fb8 100644 --- a/CMakeModules/morse/find/FindLAPACK.cmake +++ b/CMakeModules/morse/find/FindLAPACK.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -41,7 +41,7 @@ # environment variable # Note that if BLAS_DIR is set, it will also look for lapack in it ### List of vendors (BLA_VENDOR) valid in this module -## Intel(mkl), ACML,Apple, NAS, Generic +## Intel(mkl), ACML, Apple, NAS, Generic #============================================================================= # Copyright 2007-2009 Kitware, Inc. @@ -57,85 +57,65 @@ # License text for the above reference.) -# Set some colors -#if(NOT WIN32) -# string(ASCII 27 Esc) -# set(ColourReset "${Esc}[m") -# set(ColourBold "${Esc}[1m") -# set(Red "${Esc}[31m") -# set(Green "${Esc}[32m") -# set(Yellow "${Esc}[33m") -# set(Blue "${Esc}[34m") -# set(Magenta "${Esc}[35m") -# set(Cyan "${Esc}[36m") -# set(White "${Esc}[37m") -# set(BoldRed "${Esc}[1;31m") -# set(BoldGreen "${Esc}[1;32m") -# set(BoldYellow "${Esc}[1;33m") -# set(BoldBlue "${Esc}[1;34m") -# set(BoldMagenta "${Esc}[1;35m") -# set(BoldCyan "${Esc}[1;36m") -# set(BoldWhite "${Esc}[1;37m") -#endif() - ## Some macros to print status when search for headers and libs # This macro informs why the _lib_to_find file has not been found macro(Print_Find_Library_Blas_Status _libname _lib_to_find) - # save _libname upper/lower case - string(TOUPPER ${_libname} LIBNAME) - string(TOLOWER ${_libname} libname) + # save _libname upper/lower case + string(TOUPPER ${_libname} LIBNAME) + string(TOLOWER ${_libname} libname) - # print status - #message(" ") - if(${LIBNAME}_LIBDIR) - message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" - "has not been found in ${ARGN}${ColourReset}") + # print status + #message(" ") + if(${LIBNAME}_LIBDIR) + message("${Yellow}${LIBNAME}_LIBDIR is defined but ${_lib_to_find}" + "has not been found in ${ARGN}${ColourReset}") + else() + if(${LIBNAME}_DIR) + message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" + "has not been found in ${ARGN}${ColourReset}") else() - if(${LIBNAME}_DIR) - message("${Yellow}${LIBNAME}_DIR is defined but ${_lib_to_find}" - "has not been found in ${ARGN}${ColourReset}") - else() - message("${Yellow}${_lib_to_find} not found." - "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" - "are defined so that we look for ${_lib_to_find} in" - "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," - "Mac: DYLD_LIBRARY_PATH," - "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," - "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") - if(_lib_env) - message("${Yellow}${_lib_to_find} has not been found in" - "${_lib_env}${ColourReset}") - endif() - endif() + message("${Yellow}${_lib_to_find} not found." + "Nor ${LIBNAME}_DIR neither ${LIBNAME}_LIBDIR" + "are defined so that we look for ${_lib_to_find} in" + "system paths (Linux: LD_LIBRARY_PATH, Windows: LIB," + "Mac: DYLD_LIBRARY_PATH," + "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES," + "CMAKE_C_IMPLICIT_LINK_DIRECTORIES)${ColourReset}") + if(_lib_env) + message("${Yellow}${_lib_to_find} has not been found in" + "${_lib_env}${ColourReset}") + endif() endif() - message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" - "- Option 1: Provide the installation directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" - "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") + endif() + message("${BoldYellow}Please indicate where to find ${_lib_to_find}. You have three options:\n" + "- Option 1: Provide the installation directory of the library with cmake option: -D${LIBNAME}_DIR=your/path/to/${libname}/\n" + "- Option 2: Provide the directory where to find the library with cmake option: -D${LIBNAME}_LIBDIR=your/path/to/${libname}/lib/\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "- Option 4: If your library provides a PkgConfig file, make sure pkg-config finds your library${ColourReset}") endmacro() if (NOT LAPACK_FOUND) - set(LAPACK_DIR "" CACHE PATH "Installation directory of LAPACK library") - if (NOT LAPACK_FIND_QUIETLY) - message(STATUS "A cache variable, namely LAPACK_DIR, has been set to specify the install directory of LAPACK") - endif() + set(LAPACK_DIR "" CACHE PATH "Installation directory of LAPACK library") + if (NOT LAPACK_FIND_QUIETLY) + message(STATUS "A cache variable, namely LAPACK_DIR, has been set to specify the install directory of LAPACK") + endif() endif (NOT LAPACK_FOUND) option(LAPACK_VERBOSE "Print some additional information during LAPACK libraries detection" OFF) +mark_as_advanced(LAPACK_VERBOSE) if (BLAS_VERBOSE) - set(LAPACK_VERBOSE ON) + set(LAPACK_VERBOSE ON) endif () set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES) if (NOT _LANGUAGES_ MATCHES Fortran) -include(CheckFunctionExists) + include(CheckFunctionExists) else (NOT _LANGUAGES_ MATCHES Fortran) -include(CheckFortranFunctionExists) + include(CheckFortranFunctionExists) endif (NOT _LANGUAGES_ MATCHES Fortran) set(LAPACK_FOUND FALSE) @@ -144,166 +124,171 @@ set(LAPACK95_FOUND FALSE) # TODO: move this stuff to separate module macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads) -# This macro checks for the existence of the combination of fortran libraries -# given by _list. If the combination is found, this macro checks (using the -# Check_Fortran_Function_Exists macro) whether can link against that library -# combination using the name of a routine given by _name using the linker -# flags given by _flags. If the combination of libraries is found and passes -# the link test, LIBRARIES is set to the list of complete library paths that -# have been found. Otherwise, LIBRARIES is set to FALSE. - -# N.B. _prefix is the prefix applied to the names of all cached variables that -# are generated internally and marked advanced by this macro. - -set(_libraries_work TRUE) -set(${LIBRARIES}) -set(_combined_name) -set(ENV_MKLROOT "$ENV{MKLROOT}") -set(ENV_BLAS_DIR "$ENV{BLAS_DIR}") -set(ENV_BLAS_LIBDIR "$ENV{BLAS_LIBDIR}") -set(ENV_LAPACK_DIR "$ENV{LAPACK_DIR}") -set(ENV_LAPACK_LIBDIR "$ENV{LAPACK_LIBDIR}") -if (NOT _libdir) - if (BLAS_LIBDIR) + # This macro checks for the existence of the combination of fortran libraries + # given by _list. If the combination is found, this macro checks (using the + # Check_Fortran_Function_Exists macro) whether can link against that library + # combination using the name of a routine given by _name using the linker + # flags given by _flags. If the combination of libraries is found and passes + # the link test, LIBRARIES is set to the list of complete library paths that + # have been found. Otherwise, LIBRARIES is set to FALSE. + + # N.B. _prefix is the prefix applied to the names of all cached variables that + # are generated internally and marked advanced by this macro. + set(_libdir ${ARGN}) + set(_libraries_work TRUE) + set(${LIBRARIES}) + set(_combined_name) + set(ENV_MKLROOT "$ENV{MKLROOT}") + set(ENV_BLAS_DIR "$ENV{BLAS_DIR}") + set(ENV_BLAS_LIBDIR "$ENV{BLAS_LIBDIR}") + set(ENV_LAPACK_DIR "$ENV{LAPACK_DIR}") + set(ENV_LAPACK_LIBDIR "$ENV{LAPACK_LIBDIR}") + if (NOT _libdir) + if (BLAS_LIBDIR) list(APPEND _libdir "${BLAS_LIBDIR}") - elseif (BLAS_DIR) + elseif (BLAS_DIR) list(APPEND _libdir "${BLAS_DIR}") list(APPEND _libdir "${BLAS_DIR}/lib") if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${BLAS_DIR}/lib64") - list(APPEND _libdir "${BLAS_DIR}/lib/intel64") + list(APPEND _libdir "${BLAS_DIR}/lib64") + list(APPEND _libdir "${BLAS_DIR}/lib/intel64") else() - list(APPEND _libdir "${BLAS_DIR}/lib32") - list(APPEND _libdir "${BLAS_DIR}/lib/ia32") + list(APPEND _libdir "${BLAS_DIR}/lib32") + list(APPEND _libdir "${BLAS_DIR}/lib/ia32") endif() - elseif(ENV_BLAS_LIBDIR) + elseif(ENV_BLAS_LIBDIR) list(APPEND _libdir "${ENV_BLAS_LIBDIR}") - elseif(ENV_BLAS_DIR) + elseif(ENV_BLAS_DIR) list(APPEND _libdir "${ENV_BLAS_DIR}") list(APPEND _libdir "${ENV_BLAS_DIR}/lib") if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib64") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib/intel64") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib64") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib/intel64") else() - list(APPEND _libdir "${ENV_BLAS_DIR}/lib32") - list(APPEND _libdir "${ENV_BLAS_DIR}/lib/ia32") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib32") + list(APPEND _libdir "${ENV_BLAS_DIR}/lib/ia32") endif() - endif() - if (LAPACK_LIBDIR) - list(APPEND _libdir "${LAPACK_LIBDIR}") - elseif (LAPACK_DIR) - list(APPEND _libdir "${LAPACK_DIR}") - list(APPEND _libdir "${LAPACK_DIR}/lib") - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${LAPACK_DIR}/lib64") - list(APPEND _libdir "${LAPACK_DIR}/lib/intel64") - else() - list(APPEND _libdir "${LAPACK_DIR}/lib32") - list(APPEND _libdir "${LAPACK_DIR}/lib/ia32") endif() - elseif(ENV_LAPACK_LIBDIR) + if (LAPACK_LIBDIR) + list(APPEND _libdir "${LAPACK_LIBDIR}") + elseif (LAPACK_DIR) + list(APPEND _libdir "${LAPACK_DIR}") + list(APPEND _libdir "${LAPACK_DIR}/lib") + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + list(APPEND _libdir "${LAPACK_DIR}/lib64") + list(APPEND _libdir "${LAPACK_DIR}/lib/intel64") + else() + list(APPEND _libdir "${LAPACK_DIR}/lib32") + list(APPEND _libdir "${LAPACK_DIR}/lib/ia32") + endif() + elseif(ENV_LAPACK_LIBDIR) list(APPEND _libdir "${ENV_LAPACK_LIBDIR}") - elseif(ENV_LAPACK_DIR) + elseif(ENV_LAPACK_DIR) list(APPEND _libdir "${ENV_LAPACK_DIR}") list(APPEND _libdir "${ENV_LAPACK_DIR}/lib") if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${ENV_LAPACK_DIR}/lib64") - list(APPEND _libdir "${ENV_LAPACK_DIR}/lib/intel64") + list(APPEND _libdir "${ENV_LAPACK_DIR}/lib64") + list(APPEND _libdir "${ENV_LAPACK_DIR}/lib/intel64") else() - list(APPEND _libdir "${ENV_LAPACK_DIR}/lib32") - list(APPEND _libdir "${ENV_LAPACK_DIR}/lib/ia32") + list(APPEND _libdir "${ENV_LAPACK_DIR}/lib32") + list(APPEND _libdir "${ENV_LAPACK_DIR}/lib/ia32") endif() - else() - if (ENV_MKLROOT) - list(APPEND _libdir "${ENV_MKLROOT}/lib") - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - list(APPEND _libdir "${ENV_MKLROOT}/lib64") - list(APPEND _libdir "${ENV_MKLROOT}/lib/intel64") - else() - list(APPEND _libdir "${ENV_MKLROOT}/lib32") - list(APPEND _libdir "${ENV_MKLROOT}/lib/ia32") - endif() - endif() - if (WIN32) - string(REPLACE ":" ";" _libdir2 "$ENV{LIB}") - elseif (APPLE) - string(REPLACE ":" ";" _libdir2 "$ENV{DYLD_LIBRARY_PATH}") - else () - string(REPLACE ":" ";" _libdir2 "$ENV{LD_LIBRARY_PATH}") + else() + if (ENV_MKLROOT) + list(APPEND _libdir "${ENV_MKLROOT}/lib") + if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + list(APPEND _libdir "${ENV_MKLROOT}/lib64") + list(APPEND _libdir "${ENV_MKLROOT}/lib/intel64") + else() + list(APPEND _libdir "${ENV_MKLROOT}/lib32") + list(APPEND _libdir "${ENV_MKLROOT}/lib/ia32") + endif() + endif() + if (WIN32) + string(REPLACE ":" ";" _libdir2 "$ENV{LIB}") + elseif (APPLE) + string(REPLACE ":" ";" _libdir2 "$ENV{DYLD_LIBRARY_PATH}") + else () + string(REPLACE ":" ";" _libdir2 "$ENV{LD_LIBRARY_PATH}") + endif () + list(APPEND _libdir "${_libdir2}") + list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") endif () - list(APPEND _libdir "${_libdir2}") - list(APPEND _libdir "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") endif () -endif () -if (LAPACK_VERBOSE) + if (LAPACK_VERBOSE) message("${Cyan}Try to find LAPACK libraries: ${_list}") -endif () + endif () -foreach(_library ${_list}) - set(_combined_name ${_combined_name}_${_library}) + foreach(_library ${_list}) + set(_combined_name ${_combined_name}_${_library}) + + if(_libraries_work) + if (BLA_STATIC) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif ( WIN32 ) + if (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else (APPLE) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif (APPLE) + else (BLA_STATIC) + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # for ubuntu's libblas3gf and liblapack3gf packages + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) + endif () + endif (BLA_STATIC) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + HINTS ${_libdir} + NO_DEFAULT_PATH + ) + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + # Print status if not found + # ------------------------- + if (NOT ${_prefix}_${_library}_LIBRARY AND NOT LAPACK_FIND_QUIETLY AND LAPACK_VERBOSE) + Print_Find_Library_Blas_Status(lapack ${_library} ${_libdir}) + endif () + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + endif(_libraries_work) + endforeach(_library ${_list}) if(_libraries_work) - if (BLA_STATIC) - if (WIN32) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif ( WIN32 ) - if (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) - else (APPLE) - set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) - endif (APPLE) - else (BLA_STATIC) - if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - # for ubuntu's libblas3gf and liblapack3gf packages - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf) - endif () - endif (BLA_STATIC) - find_library(${_prefix}_${_library}_LIBRARY - NAMES ${_library} - HINTS ${_libdir} - ) - mark_as_advanced(${_prefix}_${_library}_LIBRARY) - # Print status if not found - # ------------------------- - if (NOT ${_prefix}_${_library}_LIBRARY AND NOT LAPACK_FIND_QUIETLY AND LAPACK_VERBOSE) - Print_Find_Library_Blas_Status(lapack ${_library} ${_libdir}) + # Test this combination of libraries. + if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND BLA_STATIC) + list(INSERT ${LIBRARIES} 0 "-Wl,--start-group") + list(APPEND ${LIBRARIES} "-Wl,--end-group") + endif() + if(UNIX AND BLA_STATIC) + set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads}) + else(UNIX AND BLA_STATIC) + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads}) + endif(UNIX AND BLA_STATIC) + if (LAPACK_VERBOSE) + message("${Cyan}LAPACK libs found. Try to compile symbol ${_name} with" + "following libraries: ${CMAKE_REQUIRED_LIBRARIES}") endif () - set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) - set(_libraries_work ${${_prefix}_${_library}_LIBRARY}) + if(NOT LAPACK_FOUND) + unset(${_prefix}${_combined_name}_WORKS CACHE) + endif() + if (NOT _LANGUAGES_ MATCHES Fortran) + check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) + else (NOT _LANGUAGES_ MATCHES Fortran) + check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS) + endif (NOT _LANGUAGES_ MATCHES Fortran) + set(CMAKE_REQUIRED_LIBRARIES) + mark_as_advanced(${_prefix}${_combined_name}_WORKS) + set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) endif(_libraries_work) -endforeach(_library ${_list}) - -if(_libraries_work) - # Test this combination of libraries. - if(UNIX AND BLA_STATIC) - set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads}) - else(UNIX AND BLA_STATIC) - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads}) - endif(UNIX AND BLA_STATIC) - if (LAPACK_VERBOSE) - message("${Cyan}LAPACK libs found. Try to compile symbol ${_name} with" - "following libraries: ${CMAKE_REQUIRED_LIBRARIES}") - endif () - if(NOT LAPACK_FOUND) - unset(${_prefix}${_combined_name}_WORKS CACHE) - endif() - if (NOT _LANGUAGES_ MATCHES Fortran) - check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS) - else (NOT _LANGUAGES_ MATCHES Fortran) - check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS) - endif (NOT _LANGUAGES_ MATCHES Fortran) - set(CMAKE_REQUIRED_LIBRARIES) - mark_as_advanced(${_prefix}${_combined_name}_WORKS) - set(_libraries_work ${${_prefix}${_combined_name}_WORKS}) -endif(_libraries_work) - - if(_libraries_work) - set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads}) - else(_libraries_work) + + if(_libraries_work) + set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads}) + else(_libraries_work) set(${LIBRARIES} FALSE) - endif(_libraries_work) + endif(_libraries_work) endmacro(Check_Lapack_Libraries) @@ -313,11 +298,11 @@ set(LAPACK_LIBRARIES) set(LAPACK95_LIBRARIES) if (NOT BLAS_FOUND) - if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_package(BLAS) - else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_package(BLAS REQUIRED) - endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_package(BLASEXT) + else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_package(BLASEXT REQUIRED) + endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) endif () if(BLAS_FOUND) @@ -330,241 +315,354 @@ if(BLAS_FOUND) endif(NOT BLA_VENDOR) endif ($ENV{BLA_VENDOR} MATCHES ".+") -if (UNIX AND NOT WIN32) - # m - find_library(M_LIBRARY NAMES m) - if(M_LIBRARY) - set(LM "-lm") - else() - set(LM "") - endif() -endif() - -#intel lapack -if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") - if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) - if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_PACKAGE(Threads) + if (UNIX AND NOT WIN32) + # m + find_library(M_LIBRARY NAMES m) + mark_as_advanced(M_LIBRARY) + if(M_LIBRARY) + set(LM "-lm") else() - find_package(Threads REQUIRED) + set(LM "") endif() + endif() - set(LAPACK_SEARCH_LIBS "") + #intel lapack + if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") - set(additional_flags "") - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(additional_flags "-Wl,--no-as-needed") - endif() + if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) + if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_PACKAGE(Threads) + else() + find_package(Threads REQUIRED) + endif() - if (BLA_F95) - set(LAPACK_mkl_SEARCH_SYMBOL "CHEEV") - set(_LIBRARIES LAPACK95_LIBRARIES) - set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES}) - - # old - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack95") - # new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_intel_c") - list(APPEND LAPACK_SEARCH_LIBS - "mkl_intel_lp64") - else() - set(LAPACK_mkl_SEARCH_SYMBOL "cheev") - set(_LIBRARIES LAPACK_LIBRARIES) - set(_BLAS_LIBRARIES ${BLAS_LIBRARIES}) - - # old - list(APPEND LAPACK_SEARCH_LIBS - "mkl_lapack") - # new >= 10.3 - list(APPEND LAPACK_SEARCH_LIBS - "mkl_gf_lp64") + set(LAPACK_SEARCH_LIBS "") + + set(additional_flags "") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(additional_flags "-Wl,--no-as-needed") + endif() + + if (BLA_F95) + set(LAPACK_mkl_SEARCH_SYMBOL "CHEEV") + set(_LIBRARIES LAPACK95_LIBRARIES) + set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES}) + + # old + list(APPEND LAPACK_SEARCH_LIBS + "mkl_lapack95") + # new >= 10.3 + list(APPEND LAPACK_SEARCH_LIBS + "mkl_intel_c") + list(APPEND LAPACK_SEARCH_LIBS + "mkl_intel_lp64") + else() + set(LAPACK_mkl_SEARCH_SYMBOL "cheev") + set(_LIBRARIES LAPACK_LIBRARIES) + set(_BLAS_LIBRARIES ${BLAS_LIBRARIES}) + + # old + list(APPEND LAPACK_SEARCH_LIBS + "mkl_lapack") + # new >= 10.3 + list(APPEND LAPACK_SEARCH_LIBS + "mkl_gf_lp64") + endif() + + # First try empty lapack libs + if (NOT ${_LIBRARIES}) + check_lapack_libraries( + ${_LIBRARIES} + LAPACK + ${LAPACK_mkl_SEARCH_SYMBOL} + "${additional_flags}" + "" + "${_BLAS_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + if(_LIBRARIES) + set(LAPACK_LINKER_FLAGS "${additional_flags}") + endif() + endif () + # Then try the search libs + foreach (IT ${LAPACK_SEARCH_LIBS}) + if (NOT ${_LIBRARIES}) + check_lapack_libraries( + ${_LIBRARIES} + LAPACK + ${LAPACK_mkl_SEARCH_SYMBOL} + "${additional_flags}" + "${IT}" + "${_BLAS_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + if(_LIBRARIES) + set(LAPACK_LINKER_FLAGS "${additional_flags}") + endif() + endif () + endforeach () + if(NOT LAPACK_FIND_QUIETLY) + if(${_LIBRARIES}) + message(STATUS "Looking for MKL LAPACK: found") + else() + message(STATUS "Looking for MKL LAPACK: not found") + endif() + endif() + endif () + endif() + + #goto lapack + if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "goto2" + "${BLAS_LIBRARIES}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for Goto LAPACK: found") + else() + message(STATUS "Looking for Goto LAPACK: not found") + endif() + endif() + endif(NOT LAPACK_LIBRARIES) + endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") + + #open lapack + if (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "openblas" + "${BLAS_LIBRARIES}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for Open LAPACK: found") + else() + message(STATUS "Looking for Open LAPACK: not found") + endif() + endif() + endif(NOT LAPACK_LIBRARIES) + endif (BLA_VENDOR STREQUAL "Open" OR BLA_VENDOR STREQUAL "All") + + # LAPACK in IBM ESSL library (requires generic lapack lib, too) + if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheevd + "" + "essl;lapack" + "${BLAS_LIBRARIES}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for IBM ESSL LAPACK: found") + else() + message(STATUS "Looking for IBM ESSL LAPACK: not found") + endif() + endif() endif() + endif () - # First try empty lapack libs - if (NOT ${_LIBRARIES}) + # LAPACK in IBM ESSL_MT library (requires generic lapack lib, too) + if (BLA_VENDOR STREQUAL "IBMESSLMT" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) check_lapack_libraries( - ${_LIBRARIES} - BLAS - ${LAPACK_mkl_SEARCH_SYMBOL} - "${additional_flags}" - "" - "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - if(_LIBRARIES) - set(LAPACK_LINKER_FLAGS "${additional_flags}") - endif() + LAPACK_LIBRARIES + LAPACK + cheevd + "" + "esslsmp;lapack" + "${BLAS_PAR_LIBRARIES}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for IBM ESSL MT LAPACK: found") + else() + message(STATUS "Looking for IBM ESSL MT LAPACK: not found") + endif() + endif() + endif() + endif () + + #acml lapack + if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") + if (BLAS_LIBRARIES MATCHES ".+acml.+") + set (LAPACK_LIBRARIES ${BLAS_LIBRARIES}) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for ACML LAPACK: found") + else() + message(STATUS "Looking for ACML LAPACK: not found") + endif() + endif() endif () - # Then try the search libs - foreach (IT ${LAPACK_SEARCH_LIBS}) - if (NOT ${_LIBRARIES}) - check_lapack_libraries( - ${_LIBRARIES} - BLAS - ${LAPACK_mkl_SEARCH_SYMBOL} - "${additional_flags}" - "${IT}" - "${_BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - if(_LIBRARIES) - set(LAPACK_LINKER_FLAGS "${additional_flags}") - endif() - endif () - endforeach () endif () -endif() -#goto lapack -if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "goto2" - "${BLAS_LIBRARIES}" - "" - ) - endif(NOT LAPACK_LIBRARIES) -endif (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All") - - -#acml lapack - if (BLA_VENDOR MATCHES "ACML.*" OR BLA_VENDOR STREQUAL "All") - if (BLAS_LIBRARIES MATCHES ".+acml.+") - set (LAPACK_LIBRARIES ${BLAS_LIBRARIES}) - endif () - endif () - -# Apple LAPACK library? -if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "Accelerate" - "${BLAS_LIBRARIES}" - "" - ) - endif(NOT LAPACK_LIBRARIES) -endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") -if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") - if ( NOT LAPACK_LIBRARIES ) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "vecLib" - "${BLAS_LIBRARIES}" - "" - ) - endif ( NOT LAPACK_LIBRARIES ) -endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") -# Generic LAPACK library? -if (BLA_VENDOR STREQUAL "Generic" OR - BLA_VENDOR STREQUAL "ATLAS" OR - BLA_VENDOR STREQUAL "All") - if ( NOT LAPACK_LIBRARIES ) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "lapack" - "${BLAS_LIBRARIES};${LM}" - "" - ) - endif ( NOT LAPACK_LIBRARIES ) -endif () + # Apple LAPACK library? + if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "Accelerate" + "${BLAS_LIBRARIES}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for Apple Accelerate LAPACK: found") + else() + message(STATUS "Looking for Apple Accelerate LAPACK: not found") + endif() + endif() + endif(NOT LAPACK_LIBRARIES) + endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All") + + if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") + if ( NOT LAPACK_LIBRARIES ) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "vecLib" + "${BLAS_LIBRARIES}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for NAS LAPACK: found") + else() + message(STATUS "Looking for NAS LAPACK: not found") + endif() + endif() + endif ( NOT LAPACK_LIBRARIES ) + endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All") + + # Generic LAPACK library? + if (BLA_VENDOR STREQUAL "Generic" OR + BLA_VENDOR STREQUAL "ATLAS" OR + BLA_VENDOR STREQUAL "All") + if ( NOT LAPACK_LIBRARIES ) + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "lapack" + "${BLAS_LIBRARIES};${LM}" + "" + ) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + message(STATUS "Looking for Generic LAPACK: found") + else() + message(STATUS "Looking for Generic LAPACK: not found") + endif() + endif() + endif ( NOT LAPACK_LIBRARIES ) + endif () else(BLAS_FOUND) message(STATUS "LAPACK requires BLAS") endif(BLAS_FOUND) if(BLA_F95) - if(LAPACK95_LIBRARIES) - set(LAPACK95_FOUND TRUE) - else(LAPACK95_LIBRARIES) - set(LAPACK95_FOUND FALSE) - endif(LAPACK95_LIBRARIES) - if(NOT LAPACK_FIND_QUIETLY) - if(LAPACK95_FOUND) - message(STATUS "A library with LAPACK95 API found.") - message(STATUS "LAPACK_LIBRARIES ${LAPACK_LIBRARIES}") - else(LAPACK95_FOUND) - message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but LAPACK 95 libraries could not be found or check of symbols failed." - "\nPlease indicate where to find LAPACK libraries. You have three options:\n" - "- Option 1: Provide the installation directory of LAPACK library with cmake option: -DLAPACK_DIR=your/path/to/lapack\n" - "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "\nTo follow libraries detection more precisely you can activate a verbose mode with -DLAPACK_VERBOSE=ON at cmake configure." - "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." - "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," - "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," - "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with LAPACK95 API not found. Please specify library location." - ) - else(LAPACK_FIND_REQUIRED) - message(STATUS - "A library with LAPACK95 API not found. Please specify library location." - ) - endif(LAPACK_FIND_REQUIRED) - endif(LAPACK95_FOUND) - endif(NOT LAPACK_FIND_QUIETLY) - set(LAPACK_FOUND "${LAPACK95_FOUND}") - set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}") + if(LAPACK95_LIBRARIES) + set(LAPACK95_FOUND TRUE) + else(LAPACK95_LIBRARIES) + set(LAPACK95_FOUND FALSE) + endif(LAPACK95_LIBRARIES) + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK95_FOUND) + message(STATUS "A library with LAPACK95 API found.") + message(STATUS "LAPACK_LIBRARIES ${LAPACK_LIBRARIES}") + else(LAPACK95_FOUND) + message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but LAPACK 95 libraries could not be found or check of symbols failed." + "\nPlease indicate where to find LAPACK libraries. You have three options:\n" + "- Option 1: Provide the installation directory of LAPACK library with cmake option: -DLAPACK_DIR=your/path/to/lapack\n" + "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "\nTo follow libraries detection more precisely you can activate a verbose mode with -DLAPACK_VERBOSE=ON at cmake configure." + "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." + "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," + "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," + "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") + if(LAPACK_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with LAPACK95 API not found. Please specify library location." + ) + else(LAPACK_FIND_REQUIRED) + message(STATUS + "A library with LAPACK95 API not found. Please specify library location." + ) + endif(LAPACK_FIND_REQUIRED) + endif(LAPACK95_FOUND) + endif(NOT LAPACK_FIND_QUIETLY) + set(LAPACK_FOUND "${LAPACK95_FOUND}") + set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}") else(BLA_F95) - if(LAPACK_LIBRARIES) - set(LAPACK_FOUND TRUE) - else(LAPACK_LIBRARIES) - set(LAPACK_FOUND FALSE) - endif(LAPACK_LIBRARIES) - - if(NOT LAPACK_FIND_QUIETLY) - if(LAPACK_FOUND) - message(STATUS "A library with LAPACK API found.") - message(STATUS "LAPACK_LIBRARIES ${LAPACK_LIBRARIES}") - else(LAPACK_FOUND) - message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but LAPACK libraries could not be found or check of symbols failed." - "\nPlease indicate where to find LAPACK libraries. You have three options:\n" - "- Option 1: Provide the installation directory of LAPACK library with cmake option: -DLAPACK_DIR=your/path/to/lapack\n" - "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" - "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" - "\nTo follow libraries detection more precisely you can activate a verbose mode with -DLAPACK_VERBOSE=ON at cmake configure." - "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." - "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," - "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," - "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") - if(LAPACK_FIND_REQUIRED) - message(FATAL_ERROR - "A required library with LAPACK API not found. Please specify library location." - ) - else(LAPACK_FIND_REQUIRED) - message(STATUS - "A library with LAPACK API not found. Please specify library location." - ) - endif(LAPACK_FIND_REQUIRED) - endif(LAPACK_FOUND) - endif(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_LIBRARIES) + set(LAPACK_FOUND TRUE) + else(LAPACK_LIBRARIES) + set(LAPACK_FOUND FALSE) + endif(LAPACK_LIBRARIES) + + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_FOUND) + message(STATUS "A library with LAPACK API found.") + message(STATUS "LAPACK_LIBRARIES ${LAPACK_LIBRARIES}") + else(LAPACK_FOUND) + message(WARNING "BLA_VENDOR has been set to ${BLA_VENDOR} but LAPACK libraries could not be found or check of symbols failed." + "\nPlease indicate where to find LAPACK libraries. You have three options:\n" + "- Option 1: Provide the installation directory of LAPACK library with cmake option: -DLAPACK_DIR=your/path/to/lapack\n" + "- Option 2: Provide the directory where to find BLAS libraries with cmake option: -DBLAS_LIBDIR=your/path/to/blas/libs\n" + "- Option 3: Update your environment variable (Linux: LD_LIBRARY_PATH, Windows: LIB, Mac: DYLD_LIBRARY_PATH)\n" + "\nTo follow libraries detection more precisely you can activate a verbose mode with -DLAPACK_VERBOSE=ON at cmake configure." + "\nYou could also specify a BLAS vendor to look for by setting -DBLA_VENDOR=blas_vendor_name." + "\nList of possible BLAS vendor: Goto, ATLAS PhiPACK, CXML, DXML, SunPerf, SCSL, SGIMATH, IBMESSL, Intel10_32 (intel mkl v10 32 bit)," + "Intel10_64lp (intel mkl v10 64 bit, lp thread model, lp64 model), Intel10_64lp_seq (intel mkl v10 64 bit, sequential code, lp64 model)," + "Intel( older versions of mkl 32 and 64 bit), ACML, ACML_MP, ACML_GPU, Apple, NAS, Generic") + if(LAPACK_FIND_REQUIRED) + message(FATAL_ERROR + "A required library with LAPACK API not found. Please specify library location." + ) + else(LAPACK_FIND_REQUIRED) + message(STATUS + "A library with LAPACK API not found. Please specify library location." + ) + endif(LAPACK_FIND_REQUIRED) + endif(LAPACK_FOUND) + endif(NOT LAPACK_FIND_QUIETLY) endif(BLA_F95) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) if (LAPACK_FOUND) - list(GET LAPACK_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") - string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") - set(LAPACK_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of LAPACK library" FORCE) - else() - set(LAPACK_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of LAPACK library" FORCE) - endif() + list(GET LAPACK_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") + string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") + set(LAPACK_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of LAPACK library" FORCE) + else() + set(LAPACK_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of LAPACK library" FORCE) + endif() endif() +mark_as_advanced(LAPACK_DIR) +mark_as_advanced(LAPACK_DIR_FOUND) diff --git a/CMakeModules/morse/find/FindLAPACKE.cmake b/CMakeModules/morse/find/FindLAPACKE.cmake index b6ea2571bfa26128e63a9797624edbfaf542c345..145f85e18c06d258be8797ddc6f6b40379223c35 100644 --- a/CMakeModules/morse/find/FindLAPACKE.cmake +++ b/CMakeModules/morse/find/FindLAPACKE.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -18,11 +18,6 @@ # LAPACKE depends on the following libraries: # - LAPACK # -# COMPONENTS are optional libraries LAPACKE could be linked with, -# Use it to drive detection of a specific compilation chain -# COMPONENTS available: -# - LAPACKEXT: to activate detection of LAPACK with LAPACKEXT cmake module -# # This module finds headers and lapacke library. # Results are reported in variables: # LAPACKE_FOUND - True if headers and requested libraries were found @@ -54,7 +49,7 @@ # Copyright 2012-2013 Emmanuel Agullo # Copyright 2012-2013 Mathieu Faverge # Copyright 2012 Cedric Castagnede -# Copyright 2013 Florent Pruvost +# Copyright 2013-2016 Florent Pruvost # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file MORSE-Copyright.txt for details. @@ -67,331 +62,317 @@ # License text for the above reference.) if (NOT LAPACKE_FOUND) - set(LAPACKE_DIR "" CACHE PATH "Installation directory of LAPACKE library") - if (NOT LAPACKE_FIND_QUIETLY) - message(STATUS "A cache variable, namely LAPACKE_DIR, has been set to specify the install directory of LAPACKE") - endif() + set(LAPACKE_DIR "" CACHE PATH "Installation directory of LAPACKE library") + if (NOT LAPACKE_FIND_QUIETLY) + message(STATUS "A cache variable, namely LAPACKE_DIR, has been set to specify the install directory of LAPACKE") + endif() endif() -# LAPACKE depends on LAPACKEXT -# try to find it specified as COMPONENTS during the call -if (LAPACKE_FIND_COMPONENTS) - foreach( component ${LAPACKE_FIND_COMPONENTS} ) - if(LAPACKE_FIND_REQUIRED_${component}) - find_package(${component} REQUIRED) - else() - find_package(${component}) - endif() - if(${component}_FOUND) - set(LAPACKE_${component}_FOUND TRUE) - else() - set(LAPACKE_${component}_FOUND FALSE) - endif() - endforeach() -endif () - # LAPACKE depends on LAPACK anyway, try to find it if (NOT LAPACK_FOUND) - if(LAPACKE_FIND_REQUIRED) - find_package(LAPACK REQUIRED) - else() - find_package(LAPACK) - endif() + if(LAPACKE_FIND_REQUIRED) + find_package(LAPACKEXT REQUIRED) + else() + find_package(LAPACKEXT) + endif() endif() # LAPACKE depends on LAPACK if (LAPACK_FOUND) - if (NOT LAPACKE_STANDALONE) - # check if a lapacke function exists in the LAPACK lib - include(CheckFunctionExists) - set(CMAKE_REQUIRED_LIBRARIES "${LAPACK_LINKER_FLAGS};${LAPACK_LIBRARIES}") - unset(LAPACKE_WORKS CACHE) - check_function_exists(LAPACKE_dgeqrf LAPACKE_WORKS) - mark_as_advanced(LAPACKE_WORKS) - set(CMAKE_REQUIRED_LIBRARIES) - - if(LAPACKE_WORKS) - if(NOT LAPACKE_FIND_QUIETLY) - message(STATUS "Looking for lapacke: test with lapack succeeds") - endif() - # test succeeds: LAPACKE is in LAPACK - set(LAPACKE_LIBRARIES "${LAPACK_LIBRARIES}") - if (LAPACK_LIBRARY_DIRS) - set(LAPACKE_LIBRARY_DIRS "${LAPACK_LIBRARY_DIRS}") - endif() - if(LAPACK_INCLUDE_DIRS) - set(LAPACKE_INCLUDE_DIRS "${LAPACK_INCLUDE_DIRS}") - endif() - if (LAPACK_LINKER_FLAGS) - set(LAPACKE_LINKER_FLAGS "${LAPACK_LINKER_FLAGS}") - endif() - endif() - endif (NOT LAPACKE_STANDALONE) - - if (LAPACKE_STANDALONE OR NOT LAPACKE_WORKS) - - if(NOT LAPACKE_WORKS AND NOT LAPACKE_FIND_QUIETLY) - message(STATUS "Looking for lapacke : test with lapack fails") - endif() - # test fails: try to find LAPACKE lib exterior to LAPACK - - # Try to find LAPACKE lib - ####################### - - # Looking for include - # ------------------- - - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - set(ENV_LAPACKE_DIR "$ENV{LAPACKE_DIR}") - set(ENV_LAPACKE_INCDIR "$ENV{LAPACKE_INCDIR}") - if(ENV_LAPACKE_INCDIR) - list(APPEND _inc_env "${ENV_LAPACKE_INCDIR}") - elseif(ENV_LAPACKE_DIR) - list(APPEND _inc_env "${ENV_LAPACKE_DIR}") - list(APPEND _inc_env "${ENV_LAPACKE_DIR}/include") - list(APPEND _inc_env "${ENV_LAPACKE_DIR}/include/lapacke") - else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() - endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) - - - # Try to find the lapacke header in the given paths - # ------------------------------------------------- - # call cmake macro to find the header path - if(LAPACKE_INCDIR) - set(LAPACKE_lapacke.h_DIRS "LAPACKE_lapacke.h_DIRS-NOTFOUND") - find_path(LAPACKE_lapacke.h_DIRS - NAMES lapacke.h - HINTS ${LAPACKE_INCDIR}) - else() - if(LAPACKE_DIR) - set(LAPACKE_lapacke.h_DIRS "LAPACKE_lapacke.h_DIRS-NOTFOUND") - find_path(LAPACKE_lapacke.h_DIRS - NAMES lapacke.h - HINTS ${LAPACKE_DIR} - PATH_SUFFIXES "include" "include/lapacke") - else() - set(LAPACKE_lapacke.h_DIRS "LAPACKE_lapacke.h_DIRS-NOTFOUND") - find_path(LAPACKE_lapacke.h_DIRS - NAMES lapacke.h - HINTS ${_inc_env}) - endif() - endif() - mark_as_advanced(LAPACKE_lapacke.h_DIRS) - - # If found, add path to cmake variable - # ------------------------------------ - if (LAPACKE_lapacke.h_DIRS) - set(LAPACKE_INCLUDE_DIRS "${LAPACKE_lapacke.h_DIRS}") - else () - set(LAPACKE_INCLUDE_DIRS "LAPACKE_INCLUDE_DIRS-NOTFOUND") - if(NOT LAPACKE_FIND_QUIETLY) - message(STATUS "Looking for lapacke -- lapacke.h not found") - endif() - endif() - - - # Looking for lib - # --------------- - - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - set(ENV_LAPACKE_LIBDIR "$ENV{LAPACKE_LIBDIR}") - if(ENV_LAPACKE_LIBDIR) - list(APPEND _lib_env "${ENV_LAPACKE_LIBDIR}") - elseif(ENV_LAPACKE_DIR) - list(APPEND _lib_env "${ENV_LAPACKE_DIR}") - list(APPEND _lib_env "${ENV_LAPACKE_DIR}/lib") - else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() - endif() - list(REMOVE_DUPLICATES _lib_env) - - # Try to find the lapacke lib in the given paths - # ---------------------------------------------- - - # call cmake macro to find the lib path - if(LAPACKE_LIBDIR) - set(LAPACKE_lapacke_LIBRARY "LAPACKE_lapacke_LIBRARY-NOTFOUND") - find_library(LAPACKE_lapacke_LIBRARY - NAMES lapacke - HINTS ${LAPACKE_LIBDIR}) - else() - if(LAPACKE_DIR) - set(LAPACKE_lapacke_LIBRARY "LAPACKE_lapacke_LIBRARY-NOTFOUND") - find_library(LAPACKE_lapacke_LIBRARY - NAMES lapacke - HINTS ${LAPACKE_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(LAPACKE_lapacke_LIBRARY "LAPACKE_lapacke_LIBRARY-NOTFOUND") - find_library(LAPACKE_lapacke_LIBRARY - NAMES lapacke - HINTS ${_lib_env}) - endif() - endif() - mark_as_advanced(LAPACKE_lapacke_LIBRARY) + if (NOT LAPACKE_STANDALONE) + # check if a lapacke function exists in the LAPACK lib + include(CheckFunctionExists) + set(CMAKE_REQUIRED_LIBRARIES "${LAPACK_LINKER_FLAGS};${LAPACK_LIBRARIES}") + unset(LAPACKE_WORKS CACHE) + check_function_exists(LAPACKE_dgeqrf LAPACKE_WORKS) + mark_as_advanced(LAPACKE_WORKS) + set(CMAKE_REQUIRED_LIBRARIES) + + if(LAPACKE_WORKS) + if(NOT LAPACKE_FIND_QUIETLY) + message(STATUS "Looking for lapacke: test with lapack succeeds") + endif() + # test succeeds: LAPACKE is in LAPACK + set(LAPACKE_LIBRARIES "${LAPACK_LIBRARIES}") + if (LAPACK_LIBRARY_DIRS) + set(LAPACKE_LIBRARY_DIRS "${LAPACK_LIBRARY_DIRS}") + endif() + if(LAPACK_INCLUDE_DIRS) + set(LAPACKE_INCLUDE_DIRS "${LAPACK_INCLUDE_DIRS}") + endif() + if (LAPACK_LINKER_FLAGS) + set(LAPACKE_LINKER_FLAGS "${LAPACK_LINKER_FLAGS}") + endif() + endif() + endif (NOT LAPACKE_STANDALONE) - # If found, add path to cmake variable - # ------------------------------------ - if (LAPACKE_lapacke_LIBRARY) - get_filename_component(lapacke_lib_path "${LAPACKE_lapacke_LIBRARY}" PATH) - # set cmake variables - set(LAPACKE_LIBRARIES "${LAPACKE_lapacke_LIBRARY}") - set(LAPACKE_LIBRARY_DIRS "${lapacke_lib_path}") - else () - set(LAPACKE_LIBRARIES "LAPACKE_LIBRARIES-NOTFOUND") - set(LAPACKE_LIBRARY_DIRS "LAPACKE_LIBRARY_DIRS-NOTFOUND") - if (NOT LAPACKE_FIND_QUIETLY) - message(STATUS "Looking for lapacke -- lib lapacke not found") - endif() - endif () + if (LAPACKE_STANDALONE OR NOT LAPACKE_WORKS) - # check a function to validate the find - if(LAPACKE_LIBRARIES) + if(NOT LAPACKE_WORKS AND NOT LAPACKE_FIND_QUIETLY) + message(STATUS "Looking for lapacke : test with lapack fails") + endif() + # test fails: try to find LAPACKE lib exterior to LAPACK + + # Try to find LAPACKE lib + ####################### + + # Looking for include + # ------------------- + + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + set(ENV_LAPACKE_DIR "$ENV{LAPACKE_DIR}") + set(ENV_LAPACKE_INCDIR "$ENV{LAPACKE_INCDIR}") + if(ENV_LAPACKE_INCDIR) + list(APPEND _inc_env "${ENV_LAPACKE_INCDIR}") + elseif(ENV_LAPACKE_DIR) + list(APPEND _inc_env "${ENV_LAPACKE_DIR}") + list(APPEND _inc_env "${ENV_LAPACKE_DIR}/include") + list(APPEND _inc_env "${ENV_LAPACKE_DIR}/include/lapacke") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) + + + # Try to find the lapacke header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(LAPACKE_INCDIR) + set(LAPACKE_lapacke.h_DIRS "LAPACKE_lapacke.h_DIRS-NOTFOUND") + find_path(LAPACKE_lapacke.h_DIRS + NAMES lapacke.h + HINTS ${LAPACKE_INCDIR}) + else() + if(LAPACKE_DIR) + set(LAPACKE_lapacke.h_DIRS "LAPACKE_lapacke.h_DIRS-NOTFOUND") + find_path(LAPACKE_lapacke.h_DIRS + NAMES lapacke.h + HINTS ${LAPACKE_DIR} + PATH_SUFFIXES "include" "include/lapacke") + else() + set(LAPACKE_lapacke.h_DIRS "LAPACKE_lapacke.h_DIRS-NOTFOUND") + find_path(LAPACKE_lapacke.h_DIRS + NAMES lapacke.h + HINTS ${_inc_env}) + endif() + endif() + mark_as_advanced(LAPACKE_lapacke.h_DIRS) + + # If found, add path to cmake variable + # ------------------------------------ + if (LAPACKE_lapacke.h_DIRS) + set(LAPACKE_INCLUDE_DIRS "${LAPACKE_lapacke.h_DIRS}") + else () + set(LAPACKE_INCLUDE_DIRS "LAPACKE_INCLUDE_DIRS-NOTFOUND") + if(NOT LAPACKE_FIND_QUIETLY) + message(STATUS "Looking for lapacke -- lapacke.h not found") + endif() + endif() - set(REQUIRED_LDFLAGS) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) - # LAPACKE - if (LAPACKE_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${LAPACKE_INCLUDE_DIRS}") - endif() - if (LAPACKE_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${LAPACKE_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${LAPACKE_LIBRARIES}") - # LAPACK - if (LAPACK_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${LAPACK_INCLUDE_DIRS}") - endif() - if (LAPACK_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${LAPACK_LIBRARY_DIRS}") - endif() - list(APPEND REQUIRED_LIBS "${LAPACK_LIBRARIES}") - if (LAPACK_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") - endif() - # Fortran - if (CMAKE_C_COMPILER_ID MATCHES "GNU") - find_library( - FORTRAN_gfortran_LIBRARY - NAMES gfortran - HINTS ${_lib_env} - ) - mark_as_advanced(FORTRAN_gfortran_LIBRARY) - if (FORTRAN_gfortran_LIBRARY) - list(APPEND REQUIRED_LIBS "${FORTRAN_gfortran_LIBRARY}") - endif() - elseif (CMAKE_C_COMPILER_ID MATCHES "Intel") - find_library( - FORTRAN_ifcore_LIBRARY - NAMES ifcore - HINTS ${_lib_env} - ) - mark_as_advanced(FORTRAN_ifcore_LIBRARY) - if (FORTRAN_ifcore_LIBRARY) - list(APPEND REQUIRED_LIBS "${FORTRAN_ifcore_LIBRARY}") - endif() - endif() - # m - find_library(M_LIBRARY NAMES m HINTS ${_lib_env}) - if(M_LIBRARY) - list(APPEND REQUIRED_LIBS "-lm") - endif() - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + # Looking for lib + # --------------- - # test link - unset(LAPACKE_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(LAPACKE_dgeqrf LAPACKE_WORKS) - mark_as_advanced(LAPACKE_WORKS) + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_LAPACKE_LIBDIR "$ENV{LAPACKE_LIBDIR}") + if(ENV_LAPACKE_LIBDIR) + list(APPEND _lib_env "${ENV_LAPACKE_LIBDIR}") + elseif(ENV_LAPACKE_DIR) + list(APPEND _lib_env "${ENV_LAPACKE_DIR}") + list(APPEND _lib_env "${ENV_LAPACKE_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() + endif() + list(REMOVE_DUPLICATES _lib_env) - if(LAPACKE_WORKS) - # save link with dependencies - set(LAPACKE_LIBRARIES_DEP "${REQUIRED_LIBS}") - set(LAPACKE_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") - set(LAPACKE_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") - set(LAPACKE_LINKER_FLAGS "${REQUIRED_LDFLAGS}") - list(REMOVE_DUPLICATES LAPACKE_LIBRARY_DIRS_DEP) - list(REMOVE_DUPLICATES LAPACKE_INCLUDE_DIRS_DEP) - list(REMOVE_DUPLICATES LAPACKE_LINKER_FLAGS) - else() - if(NOT LAPACKE_FIND_QUIETLY) - message(STATUS "Looking for lapacke: test of LAPACKE_dgeqrf with lapacke and lapack libraries fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(LAPACKE_LIBRARIES) + # Try to find the lapacke lib in the given paths + # ---------------------------------------------- - endif (LAPACKE_STANDALONE OR NOT LAPACKE_WORKS) + # call cmake macro to find the lib path + if(LAPACKE_LIBDIR) + set(LAPACKE_lapacke_LIBRARY "LAPACKE_lapacke_LIBRARY-NOTFOUND") + find_library(LAPACKE_lapacke_LIBRARY + NAMES lapacke + HINTS ${LAPACKE_LIBDIR}) + else() + if(LAPACKE_DIR) + set(LAPACKE_lapacke_LIBRARY "LAPACKE_lapacke_LIBRARY-NOTFOUND") + find_library(LAPACKE_lapacke_LIBRARY + NAMES lapacke + HINTS ${LAPACKE_DIR} + PATH_SUFFIXES lib lib32 lib64) + else() + set(LAPACKE_lapacke_LIBRARY "LAPACKE_lapacke_LIBRARY-NOTFOUND") + find_library(LAPACKE_lapacke_LIBRARY + NAMES lapacke + HINTS ${_lib_env}) + endif() + endif() + mark_as_advanced(LAPACKE_lapacke_LIBRARY) + + # If found, add path to cmake variable + # ------------------------------------ + if (LAPACKE_lapacke_LIBRARY) + get_filename_component(lapacke_lib_path "${LAPACKE_lapacke_LIBRARY}" PATH) + # set cmake variables + set(LAPACKE_LIBRARIES "${LAPACKE_lapacke_LIBRARY}") + set(LAPACKE_LIBRARY_DIRS "${lapacke_lib_path}") + else () + set(LAPACKE_LIBRARIES "LAPACKE_LIBRARIES-NOTFOUND") + set(LAPACKE_LIBRARY_DIRS "LAPACKE_LIBRARY_DIRS-NOTFOUND") + if (NOT LAPACKE_FIND_QUIETLY) + message(STATUS "Looking for lapacke -- lib lapacke not found") + endif() + endif () + + # check a function to validate the find + if(LAPACKE_LIBRARIES) + + set(REQUIRED_LDFLAGS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # LAPACKE + if (LAPACKE_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${LAPACKE_INCLUDE_DIRS}") + endif() + if (LAPACKE_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${LAPACKE_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${LAPACKE_LIBRARIES}") + # LAPACK + if (LAPACK_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${LAPACK_INCLUDE_DIRS}") + endif() + if (LAPACK_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${LAPACK_LIBRARY_DIRS}") + endif() + list(APPEND REQUIRED_LIBS "${LAPACK_LIBRARIES}") + if (LAPACK_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") + endif() + # Fortran + if (CMAKE_C_COMPILER_ID MATCHES "GNU") + find_library( + FORTRAN_gfortran_LIBRARY + NAMES gfortran + HINTS ${_lib_env} + ) + mark_as_advanced(FORTRAN_gfortran_LIBRARY) + if (FORTRAN_gfortran_LIBRARY) + list(APPEND REQUIRED_LIBS "${FORTRAN_gfortran_LIBRARY}") + endif() + elseif (CMAKE_C_COMPILER_ID MATCHES "Intel") + find_library( + FORTRAN_ifcore_LIBRARY + NAMES ifcore + HINTS ${_lib_env} + ) + mark_as_advanced(FORTRAN_ifcore_LIBRARY) + if (FORTRAN_ifcore_LIBRARY) + list(APPEND REQUIRED_LIBS "${FORTRAN_ifcore_LIBRARY}") + endif() + endif() + # m + find_library(M_LIBRARY NAMES m HINTS ${_lib_env}) + mark_as_advanced(M_LIBRARY) + if(M_LIBRARY) + list(APPEND REQUIRED_LIBS "-lm") + endif() + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(LAPACKE_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(LAPACKE_dgeqrf LAPACKE_WORKS) + mark_as_advanced(LAPACKE_WORKS) + + if(LAPACKE_WORKS) + # save link with dependencies + set(LAPACKE_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(LAPACKE_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(LAPACKE_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(LAPACKE_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES LAPACKE_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES LAPACKE_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES LAPACKE_LINKER_FLAGS) + else() + if(NOT LAPACKE_FIND_QUIETLY) + message(STATUS "Looking for lapacke: test of LAPACKE_dgeqrf with lapacke and lapack libraries fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(LAPACKE_LIBRARIES) + + endif (LAPACKE_STANDALONE OR NOT LAPACKE_WORKS) else(LAPACK_FOUND) - if (NOT LAPACKE_FIND_QUIETLY) - message(STATUS "LAPACKE requires LAPACK but LAPACK has not been found." - "Please look for LAPACK first.") - endif() + if (NOT LAPACKE_FIND_QUIETLY) + message(STATUS "LAPACKE requires LAPACK but LAPACK has not been found." + "Please look for LAPACK first.") + endif() endif(LAPACK_FOUND) if (LAPACKE_LIBRARIES) - list(GET LAPACKE_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") - string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") - set(LAPACKE_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of LAPACKE library" FORCE) - else() - set(LAPACKE_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of LAPACKE library" FORCE) - endif() + list(GET LAPACKE_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)") + string(REGEX REPLACE "(/lib(32|64)?$)|(/lib/intel64$|/lib/ia32$)" "" not_cached_dir "${first_lib_path}") + set(LAPACKE_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of LAPACKE library" FORCE) + else() + set(LAPACKE_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of LAPACKE library" FORCE) + endif() endif() +mark_as_advanced(LAPACKE_DIR) +mark_as_advanced(LAPACKE_DIR_FOUND) # check that LAPACKE has been found # --------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LAPACKE DEFAULT_MSG - LAPACKE_LIBRARIES - LAPACKE_WORKS) + LAPACKE_LIBRARIES + LAPACKE_WORKS) diff --git a/CMakeModules/morse/find/FindLAPACKEXT.cmake b/CMakeModules/morse/find/FindLAPACKEXT.cmake index dc608cc741221f20010cf11b5f42839ac7e3b0db..bf62c3d7071cce623a64a78aa55c52935b0e5256 100644 --- a/CMakeModules/morse/find/FindLAPACKEXT.cmake +++ b/CMakeModules/morse/find/FindLAPACKEXT.cmake @@ -13,10 +13,8 @@ # This module allows to find LAPACK libraries by calling the official FindLAPACK module # and handles the creation of different library lists whether the user wishes to link # with a sequential LAPACK or a multihreaded (LAPACK_SEQ_LIBRARIES and LAPACK_PAR_LIBRARIES). -# LAPACK is detected with a FindLAPACK call then if the LAPACK vendor is in the following list, -# Intel mkl, Goto, Openlapack, ACML, IBMESSL -# then the module tries find the corresponding multithreaded libraries -# LAPACK_LIBRARIES does not exists anymore. +# LAPACK is detected with a FindLAPACK call and if the BLAS vendor is in the following list, +# Intel mkl, ACML then the module tries find the corresponding multithreaded libraries # # The following variables have been added to manage links with sequential or multithreaded # versions: @@ -42,255 +40,311 @@ # (To distribute this file outside of Morse, substitute the full # License text for the above reference.) +# macro to factorize this call +macro(find_package_lapack) + if(LAPACKEXT_FIND_REQUIRED) + if(LAPACKEXT_FIND_QUIETLY) + find_package(LAPACK REQUIRED QUIET) + else() + find_package(LAPACK REQUIRED) + endif() + else() + if(LAPACKEXT_FIND_QUIETLY) + find_package(LAPACK QUIET) + else() + find_package(LAPACK) + endif() + endif() +endmacro() # LAPACKEXT depends on BLASEXT # call our extended module for BLAS #---------------------------------- if (NOT BLAS_FOUND) - if(LAPACKEXT_FIND_REQUIRED) - find_package(BLASEXT REQUIRED) + if(LAPACKEXT_FIND_REQUIRED) + if(LAPACKEXT_FIND_QUIETLY) + find_package(BLAS REQUIRED QUIET) + else() + find_package(BLAS REQUIRED) + endif() + else() + if(LAPACKEXT_FIND_QUIETLY) + find_package(BLAS QUIET) else() - find_package(BLASEXT) + find_package(BLAS) endif() + endif() endif () +if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "In FindLAPACKEXT") +endif() if(BLA_VENDOR MATCHES "Intel*") - ### - # look for include path if the LAPACK vendor is Intel - ### + ### + # look for include path if the LAPACK vendor is Intel + ### + + # gather system include paths + unset(_inc_env) + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + set(ENV_MKLROOT "$ENV{MKLROOT}") + if (ENV_MKLROOT) + list(APPEND _inc_env "${ENV_MKLROOT}/include") + endif() + list(REMOVE_DUPLICATES _inc_env) - # gather system include paths - unset(_inc_env) - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + if (BLAS_DIR) + set(LAPACK_DIR ${BLAS_DIR}) + endif () + if (BLAS_INCDIR) + set(LAPACK_INCDIR ${BLAS_INCDIR}) + endif () + # find mkl.h inside known include paths + set(LAPACK_mkl_lapack.h_INCLUDE_DIRS "LAPACK_mkl_lapack.h_INCLUDE_DIRS-NOTFOUND") + if(LAPACK_INCDIR) + find_path(LAPACK_mkl_lapack.h_INCLUDE_DIRS + NAMES mkl_lapack.h + HINTS ${LAPACK_INCDIR}) + else() + if(LAPACK_DIR) + find_path(LAPACK_mkl_lapack.h_INCLUDE_DIRS + NAMES mkl_lapack.h + HINTS ${LAPACK_DIR} + PATH_SUFFIXES include) else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") + find_path(LAPACK_mkl_lapack.h_INCLUDE_DIRS + NAMES mkl_lapack.h + HINTS ${_inc_env}) endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) + endif() + mark_as_advanced(LAPACK_mkl_lapack.h_INCLUDE_DIRS) + ## Print status if not found + ## ------------------------- + #if (NOT LAPACK_mkl_lapack.h_INCLUDE_DIRS) + # Print_Find_Header_Status(lapack mkl_lapack.h) + #endif () + set(LAPACK_INCLUDE_DIRS "") + if(LAPACK_mkl_lapack.h_INCLUDE_DIRS) + list(APPEND LAPACK_INCLUDE_DIRS "${LAPACK_mkl_lapack.h_INCLUDE_DIRS}" ) + endif() + + ### + # look for libs + ### + + if (BLA_VENDOR MATCHES "Intel10_64lp*") + ## look for the sequential version + set(BLA_VENDOR "Intel10_64lp_seq") + endif() + find_package_lapack() - if (BLAS_DIR) - set(LAPACK_DIR ${BLAS_DIR}) - endif () - if (BLAS_INCDIR) - set(LAPACK_INCDIR ${BLAS_INCDIR}) - endif () - # find mkl.h inside known include paths - set(LAPACK_mkl_lapack.h_INCLUDE_DIRS "LAPACK_mkl_lapack.h_INCLUDE_DIRS-NOTFOUND") - if(LAPACK_INCDIR) - find_path(LAPACK_mkl_lapack.h_INCLUDE_DIRS - NAMES mkl_lapack.h - HINTS ${LAPACK_INCDIR}) + if (LAPACK_FOUND) + if(BLAS_SEQ_LIBRARIES) + set(LAPACK_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES}") else() - if(LAPACK_DIR) - find_path(LAPACK_mkl_lapack.h_INCLUDE_DIRS - NAMES mkl_lapack.h - HINTS ${LAPACK_DIR} - PATH_SUFFIXES include) - else() - find_path(LAPACK_mkl_lapack.h_INCLUDE_DIRS - NAMES mkl_lapack.h - HINTS ${_inc_env}) - endif() + set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") endif() - mark_as_advanced(LAPACK_mkl_lapack.h_INCLUDE_DIRS) - ## Print status if not found - ## ------------------------- - #if (NOT LAPACK_mkl_lapack.h_INCLUDE_DIRS) - # Print_Find_Header_Status(lapack mkl_lapack.h) - #endif () - set(LAPACK_INCLUDE_DIRS "") - if(LAPACK_mkl_lapack.h_INCLUDE_DIRS) - list(APPEND LAPACK_INCLUDE_DIRS "${LAPACK_mkl_lapack.h_INCLUDE_DIRS}" ) + # if BLAS Intel 10 64 bit -> save sequential and multithreaded versions + if(BLA_VENDOR MATCHES "Intel10_64lp*") + if(BLAS_PAR_LIBRARIES) + set(LAPACK_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES}") + else() + set(LAPACK_PAR_LIBRARIES "${LAPACK_PAR_LIBRARIES-NOTFOUND}") + endif() endif() + endif() - ### - # look for libs - ### +elseif(BLA_VENDOR MATCHES "IBMESSL*") - if (BLA_VENDOR MATCHES "Intel10_64lp*") - ## look for the sequential version - set(BLA_VENDOR "Intel10_64lp_seq") - endif() + ## look for the sequential version + set(BLA_VENDOR "IBMESSL") + find_package_lapack() - if(LAPACKEXT_FIND_REQUIRED) - find_package(LAPACK REQUIRED) + if (LAPACK_FOUND) + if(LAPACK_LIBRARIES) + set(LAPACK_SEQ_LIBRARIES "${LAPACK_LIBRARIES}") else() - find_package(LAPACK) + set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") endif() + endif() + + ## look for the multithreaded version + set(BLA_VENDOR "IBMESSLMT") + find_package_lapack() - if (LAPACK_FOUND) - if(BLAS_SEQ_LIBRARIES) - set(LAPACK_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES}") - else() - set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") - endif() - # if BLAS Intel 10 64 bit -> save sequential and multithreaded versions - if(BLA_VENDOR MATCHES "Intel10_64lp*") - if(BLAS_PAR_LIBRARIES) - set(LAPACK_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES}") - else() - set(LAPACK_PAR_LIBRARIES "${LAPACK_PAR_LIBRARIES-NOTFOUND}") - endif() - endif() + if (LAPACK_FOUND) + if(LAPACK_LIBRARIES) + set(LAPACK_PAR_LIBRARIES "${LAPACK_LIBRARIES}") + else() + set(LAPACK_PAR_LIBRARIES "${LAPACK_PAR_LIBRARIES-NOTFOUND}") endif() + endif() elseif(BLA_VENDOR MATCHES "ACML*") - ### - # look for libs - ### - if(LAPACKEXT_FIND_REQUIRED) - find_package(LAPACK REQUIRED) + ### + # look for libs + ### + find_package_lapack() + + if (LAPACK_FOUND) + if(BLAS_SEQ_LIBRARIES) + set(LAPACK_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES}") else() - find_package(LAPACK) + set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") endif() - - if (LAPACK_FOUND) - if(BLAS_SEQ_LIBRARIES) - set(LAPACK_SEQ_LIBRARIES "${BLAS_SEQ_LIBRARIES}") - else() - set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") - endif() - if(BLAS_PAR_LIBRARIES) - set(LAPACK_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES}") - else() - set(LAPACK_PAR_LIBRARIES "${LAPACK_PAR_LIBRARIES-NOTFOUND}") - endif() + if(BLAS_PAR_LIBRARIES) + set(LAPACK_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES}") + else() + set(LAPACK_PAR_LIBRARIES "${LAPACK_PAR_LIBRARIES-NOTFOUND}") endif() + endif() else() - ## look for a sequential version - # call to the cmake official FindLAPACK module - # This module sets the following variables: - # LAPACK_FOUND - set to true if a library implementing the LAPACK interface - # is found - # LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l - # and -L). - # LAPACK_LIBRARIES - uncached list of libraries (using full path name) to - # link against to use LAPACK - # LAPACK95_LIBRARIES - uncached list of libraries (using full path name) - # to link against to use LAPACK95 interface - # LAPACK95_FOUND - set to true if a library implementing the LAPACK f95 interface - # is found - # BLA_STATIC if set on this determines what kind of linkage we do (static) - # BLA_VENDOR if set checks only the specified vendor, if not set checks - # all the possibilities - # BLA_F95 if set on tries to find the f95 interfaces for LAPACK/LAPACK - # Remark: it looks only into paths contained in the system environment variables - if(LAPACKEXT_FIND_REQUIRED) - find_package(LAPACK REQUIRED) - else() - find_package(LAPACK) - endif() + ## look for a sequential version + # call to the cmake official FindLAPACK module + # This module sets the following variables: + # LAPACK_FOUND - set to true if a library implementing the LAPACK interface + # is found + # LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l + # and -L). + # LAPACK_LIBRARIES - uncached list of libraries (using full path name) to + # link against to use LAPACK + # LAPACK95_LIBRARIES - uncached list of libraries (using full path name) + # to link against to use LAPACK95 interface + # LAPACK95_FOUND - set to true if a library implementing the LAPACK f95 interface + # is found + # BLA_STATIC if set on this determines what kind of linkage we do (static) + # BLA_VENDOR if set checks only the specified vendor, if not set checks + # all the possibilities + # BLA_F95 if set on tries to find the f95 interfaces for LAPACK/LAPACK + # Remark: it looks only into paths contained in the system environment variables + find_package_lapack() - if(LAPACK_FOUND) - set(LAPACK_SEQ_LIBRARIES "${LAPACK_LIBRARIES}") - else() - set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") - endif() - set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") + if(LAPACK_FOUND) + set(LAPACK_SEQ_LIBRARIES "${LAPACK_LIBRARIES}") + else() + set(LAPACK_SEQ_LIBRARIES "${LAPACK_SEQ_LIBRARIES-NOTFOUND}") + endif() + set(BLAS_PAR_LIBRARIES "${BLAS_PAR_LIBRARIES-NOTFOUND}") endif() if (LAPACK_SEQ_LIBRARIES) - set(LAPACK_LIBRARIES "${LAPACK_SEQ_LIBRARIES}") + set(LAPACK_LIBRARIES "${LAPACK_SEQ_LIBRARIES}") endif() # extract libs paths # remark: because it is not given by find_package(LAPACK) set(LAPACK_LIBRARY_DIRS "") +string(REPLACE " " ";" LAPACK_LIBRARIES "${LAPACK_LIBRARIES}") foreach(lapack_lib ${LAPACK_LIBRARIES}) + if (EXISTS "${lapack_lib}") get_filename_component(a_lapack_lib_dir "${lapack_lib}" PATH) list(APPEND LAPACK_LIBRARY_DIRS "${a_lapack_lib_dir}" ) + else() + string(REPLACE "-L" "" lapack_lib "${lapack_lib}") + if (EXISTS "${lapack_lib}") + list(APPEND LAPACK_LIBRARY_DIRS "${lapack_lib}" ) + else() + get_filename_component(a_lapack_lib_dir "${lapack_lib}" PATH) + if (EXISTS "${a_lapack_lib_dir}") + list(APPEND LAPACK_LIBRARY_DIRS "${a_lapack_lib_dir}" ) + endif() + endif() + endif() endforeach() if (LAPACK_LIBRARY_DIRS) - list(REMOVE_DUPLICATES LAPACK_LIBRARY_DIRS) + list(REMOVE_DUPLICATES LAPACK_LIBRARY_DIRS) endif () - -# message(STATUS "LAPACK_FOUND: ${LAPACK_FOUND}") -# message(STATUS "LAPACK_VENDOR: ${LAPACK_VENDOR}") -# message(STATUS "LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}") -# message(STATUS "LAPACK_SEQ_LIBRARIES: ${LAPACK_SEQ_LIBRARIES}") -# message(STATUS "LAPACK_PAR_LIBRARIES: ${LAPACK_PAR_LIBRARIES}") -# message(STATUS "LAPACK_INCLUDE_DIRS: ${LAPACK_INCLUDE_DIRS}") -# message(STATUS "LAPACK_LIBRARY_DIRS: ${LAPACK_LIBRARY_DIRS}") - # check that LAPACK has been found # --------------------------------- include(FindPackageHandleStandardArgs) if(BLA_VENDOR MATCHES "Intel*") - if(BLA_VENDOR MATCHES "Intel10_64lp*") - if(NOT LAPACKEXT_FIND_QUIETLY) - message(STATUS "LAPACK found is Intel MKL:" - "we manage two lists of libs," - " one sequential and one parallel (see" - "LAPACK_SEQ_LIBRARIES and LAPACK_PAR_LIBRARIES)") - message(STATUS "LAPACK sequential libraries stored in" - "LAPACK_SEQ_LIBRARIES") - endif() - find_package_handle_standard_args(LAPACK DEFAULT_MSG - LAPACK_SEQ_LIBRARIES - LAPACK_LIBRARY_DIRS - LAPACK_INCLUDE_DIRS) - if(LAPACK_PAR_LIBRARIES) - if(NOT LAPACKEXT_FIND_QUIETLY) - message(STATUS "LAPACK parallel libraries stored in" - "LAPACK_PAR_LIBRARIES") - endif() - find_package_handle_standard_args(LAPACK DEFAULT_MSG - LAPACK_PAR_LIBRARIES) - endif() + if(BLA_VENDOR MATCHES "Intel10_64lp*") + if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "LAPACK found is Intel MKL:" + "\n we manage two lists of libs, one sequential and one parallel" + "\n (see LAPACK_SEQ_LIBRARIES and LAPACK_PAR_LIBRARIES)") + message(STATUS "LAPACK sequential libraries stored in LAPACK_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_SEQ_LIBRARIES + LAPACK_LIBRARY_DIRS + LAPACK_INCLUDE_DIRS) + if(LAPACK_PAR_LIBRARIES) + if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "LAPACK parallel libraries stored in LAPACK_PAR_LIBRARIES") + endif() + find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_PAR_LIBRARIES) + endif() - else() - if(NOT LAPACKEXT_FIND_QUIETLY) - message(STATUS "LAPACK sequential libraries stored in" - "LAPACK_SEQ_LIBRARIES") - endif() - find_package_handle_standard_args(LAPACK DEFAULT_MSG - LAPACK_SEQ_LIBRARIES - LAPACK_LIBRARY_DIRS - LAPACK_INCLUDE_DIRS) + else() + if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "LAPACK sequential libraries stored in LAPACK_SEQ_LIBRARIES") endif() + find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_SEQ_LIBRARIES + LAPACK_LIBRARY_DIRS + LAPACK_INCLUDE_DIRS) + endif() elseif(BLA_VENDOR MATCHES "ACML*") + if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "LAPACK found is ACML:" + "\n we manage two lists of libs, one sequential and one parallel" + "\n (see LAPACK_SEQ_LIBRARIES and LAPACK_PAR_LIBRARIES)") + message(STATUS "LAPACK sequential libraries stored in LAPACK_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_SEQ_LIBRARIES + LAPACK_LIBRARY_DIRS) + if(LAPACK_PAR_LIBRARIES) if(NOT LAPACKEXT_FIND_QUIETLY) - message(STATUS "LAPACK found is ACML:" - "we manage two lists of libs," - " one sequential and one parallel (see" - "LAPACK_SEQ_LIBRARIES and LAPACK_PAR_LIBRARIES)") - message(STATUS "LAPACK sequential libraries stored in" - "LAPACK_SEQ_LIBRARIES") + message(STATUS "LAPACK parallel libraries stored in LAPACK_PAR_LIBRARIES") endif() find_package_handle_standard_args(LAPACK DEFAULT_MSG - LAPACK_SEQ_LIBRARIES - LAPACK_LIBRARY_DIRS - LAPACK_INCLUDE_DIRS) - if(LAPACK_PAR_LIBRARIES) - if(NOT LAPACKEXT_FIND_QUIETLY) - message(STATUS "LAPACK parallel libraries stored in" - "LAPACK_PAR_LIBRARIES") - endif() - find_package_handle_standard_args(LAPACK DEFAULT_MSG - LAPACK_PAR_LIBRARIES) - endif() -else() + LAPACK_PAR_LIBRARIES) + endif() +elseif(BLA_VENDOR MATCHES "IBMESSL*") + if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "LAPACK found is IBMESSL:" + "\n we manage two lists of libs, one sequential and one parallel" + "\n (see LAPACK_SEQ_LIBRARIES and LAPACK_PAR_LIBRARIES)") + message(STATUS "LAPACK sequential libraries stored in LAPACK_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_SEQ_LIBRARIES + LAPACK_LIBRARY_DIRS) + if(LAPACK_PAR_LIBRARIES) if(NOT LAPACKEXT_FIND_QUIETLY) - message(STATUS "LAPACK sequential libraries stored in" - "LAPACK_SEQ_LIBRARIES") + message(STATUS "LAPACK parallel libraries stored in LAPACK_PAR_LIBRARIES") endif() find_package_handle_standard_args(LAPACK DEFAULT_MSG - LAPACK_SEQ_LIBRARIES - LAPACK_LIBRARY_DIRS) + LAPACK_PAR_LIBRARIES) + endif() +else() + if(NOT LAPACKEXT_FIND_QUIETLY) + message(STATUS "LAPACK sequential libraries stored in LAPACK_SEQ_LIBRARIES") + endif() + find_package_handle_standard_args(LAPACK DEFAULT_MSG + LAPACK_SEQ_LIBRARIES + LAPACK_LIBRARY_DIRS) endif() diff --git a/CMakeModules/morse/find/FindMAGMA.cmake b/CMakeModules/morse/find/FindMAGMA.cmake index e8bdd072ddf18c8ccf7cd0d2282efe3919278218..d3eda98d3ccd8036d2fcc5f42e9052ce03b573e6 100644 --- a/CMakeModules/morse/find/FindMAGMA.cmake +++ b/CMakeModules/morse/find/FindMAGMA.cmake @@ -3,7 +3,7 @@ # @copyright (c) 2009-2014 The University of Tennessee and The University # of Tennessee Research Foundation. # All rights reserved. -# @copyright (c) 2012-2014 Inria. All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. # @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. # ### @@ -48,7 +48,7 @@ # Copyright 2012-2013 Emmanuel Agullo # Copyright 2012-2013 Mathieu Faverge # Copyright 2012 Cedric Castagnede -# Copyright 2013 Florent Pruvost +# Copyright 2013-2016 Florent Pruvost # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file MORSE-Copyright.txt for details. @@ -62,42 +62,42 @@ if(NOT MAGMA_FOUND) - set(MAGMA_DIR "" CACHE PATH "Installation directory of MAGMA library") - if (NOT MAGMA_FIND_QUIETLY) - message(STATUS "A cache variable, namely MAGMA_DIR, has been set to specify the install directory of MAGMA") - endif() + set(MAGMA_DIR "" CACHE PATH "Installation directory of MAGMA library") + if (NOT MAGMA_FIND_QUIETLY) + message(STATUS "A cache variable, namely MAGMA_DIR, has been set to specify the install directory of MAGMA") + endif() endif(NOT MAGMA_FOUND) # MAGMA depends on CUDA anyway, try to find it if (NOT CUDA_FOUND) - if(MAGMA_FIND_REQUIRED) - find_package(CUDA REQUIRED) - else() - find_package(CUDA) - endif() + if(MAGMA_FIND_REQUIRED) + find_package(CUDA REQUIRED) + else() + find_package(CUDA) + endif() endif() # MAGMA depends on cuBLAS which should come with CUDA, if not found -> error if (NOT CUDA_CUBLAS_LIBRARIES) - if(MAGMA_FIND_REQUIRED) - message(FATAL_ERROR "Looking for MAGMA - MAGMA depends on cuBLAS which has " - "not been found (should come with cuda install)") - endif() + if(MAGMA_FIND_REQUIRED) + message(FATAL_ERROR "Looking for MAGMA - MAGMA depends on cuBLAS which has " + "not been found (should come with cuda install)") + endif() endif() # MAGMA depends on LAPACK anyway, try to find it if (NOT LAPACK_FOUND) - if(MAGMA_FIND_REQUIRED) - find_package(LAPACK REQUIRED) - else() - find_package(LAPACK) - endif() + if(MAGMA_FIND_REQUIRED) + find_package(LAPACKEXT REQUIRED) + else() + find_package(LAPACKEXT) + endif() endif() # MAGMA depends on CBLAS anyway, try to find it if (NOT CBLAS_FOUND) - if(MAGMA_FIND_REQUIRED) - find_package(CBLAS REQUIRED) - else() - find_package(CBLAS) - endif() + if(MAGMA_FIND_REQUIRED) + find_package(CBLAS REQUIRED) + else() + find_package(CBLAS) + endif() endif() set(ENV_MAGMA_DIR "$ENV{MAGMA_DIR}") @@ -105,7 +105,7 @@ set(ENV_MAGMA_INCDIR "$ENV{MAGMA_INCDIR}") set(ENV_MAGMA_LIBDIR "$ENV{MAGMA_LIBDIR}") set(MAGMA_GIVEN_BY_USER "FALSE") if ( MAGMA_DIR OR ( MAGMA_INCDIR AND MAGMA_LIBDIR) OR ENV_MAGMA_DIR OR (ENV_MAGMA_INCDIR AND ENV_MAGMA_LIBDIR) ) - set(MAGMA_GIVEN_BY_USER "TRUE") + set(MAGMA_GIVEN_BY_USER "TRUE") endif() # Optionally use pkg-config to detect include/library dirs (if pkg-config is available) @@ -114,323 +114,325 @@ include(FindPkgConfig) find_package(PkgConfig QUIET) if(PKG_CONFIG_EXECUTABLE AND NOT MAGMA_GIVEN_BY_USER) - pkg_search_module(MAGMA magma) - if (NOT MAGMA_FIND_QUIETLY) - if (MAGMA_FOUND AND MAGMA_LIBRARIES) - message(STATUS "Looking for MAGMA - found using PkgConfig") - #if(NOT MAGMA_INCLUDE_DIRS) - # message("${Magenta}MAGMA_INCLUDE_DIRS is empty using PkgConfig." - # "Perhaps the path to magma headers is already present in your" - # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") - #endif() - else() - message("${Magenta}Looking for MAGMA - not found using PkgConfig. " - "Perhaps you should add the directory containing magma.pc " - "to the PKG_CONFIG_PATH environment variable.${ColourReset}") - endif() + pkg_search_module(MAGMA magma) + if (NOT MAGMA_FIND_QUIETLY) + if (MAGMA_FOUND AND MAGMA_LIBRARIES) + message(STATUS "Looking for MAGMA - found using PkgConfig") + #if(NOT MAGMA_INCLUDE_DIRS) + # message("${Magenta}MAGMA_INCLUDE_DIRS is empty using PkgConfig." + # "Perhaps the path to magma headers is already present in your" + # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") + #endif() + else() + message(STATUS "${Magenta}Looking for MAGMA - not found using PkgConfig. " + "\n Perhaps you should add the directory containing magma.pc " + "\n to the PKG_CONFIG_PATH environment variable.${ColourReset}") endif() + endif() - if (MAGMA_FIND_VERSION_EXACT) - if( NOT (MAGMA_FIND_VERSION_MAJOR STREQUAL MAGMA_VERSION_MAJOR) OR - NOT (MAGMA_FIND_VERSION_MINOR STREQUAL MAGMA_VERSION_MINOR) ) - if(NOT MAGMA_FIND_QUIETLY) - message(FATAL_ERROR - "MAGMA version found is ${MAGMA_VERSION_STRING} " - "when required is ${MAGMA_FIND_VERSION}") - endif() - endif() - else() - # if the version found is older than the required then error - if( (MAGMA_FIND_VERSION_MAJOR STRGREATER MAGMA_VERSION_MAJOR) OR - (MAGMA_FIND_VERSION_MINOR STRGREATER MAGMA_VERSION_MINOR) ) - if(NOT MAGMA_FIND_QUIETLY) - message(FATAL_ERROR - "MAGMA version found is ${MAGMA_VERSION_STRING} " - "when required is ${MAGMA_FIND_VERSION} or newer") - endif() - endif() + if (MAGMA_FIND_VERSION_EXACT) + if( NOT (MAGMA_FIND_VERSION_MAJOR STREQUAL MAGMA_VERSION_MAJOR) OR + NOT (MAGMA_FIND_VERSION_MINOR STREQUAL MAGMA_VERSION_MINOR) ) + if(NOT MAGMA_FIND_QUIETLY) + message(FATAL_ERROR + "MAGMA version found is ${MAGMA_VERSION_STRING} " + "when required is ${MAGMA_FIND_VERSION}") + endif() endif() + else() + # if the version found is older than the required then error + if( (MAGMA_FIND_VERSION_MAJOR STRGREATER MAGMA_VERSION_MAJOR) OR + (MAGMA_FIND_VERSION_MINOR STRGREATER MAGMA_VERSION_MINOR) ) + if(NOT MAGMA_FIND_QUIETLY) + message(FATAL_ERROR + "MAGMA version found is ${MAGMA_VERSION_STRING} " + "when required is ${MAGMA_FIND_VERSION} or newer") + endif() + endif() + endif() - # if pkg-config is used: these variables are empty - # the pkg_search_module call will set the following: - # MAGMA_LDFLAGS: all required linker flags - # MAGMA_CFLAGS: all required cflags - set(MAGMA_INCLUDE_DIRS_DEP "") - set(MAGMA_LIBRARY_DIRS_DEP "") - set(MAGMA_LIBRARIES_DEP "") - # replace it anyway: we should update it with dependencies given by pkg-config - set(MAGMA_INCLUDE_DIRS_DEP "${MAGMA_INCLUDE_DIRS}") - set(MAGMA_LIBRARY_DIRS_DEP "${MAGMA_LIBRARY_DIRS}") - set(MAGMA_LIBRARIES_DEP "${MAGMA_LIBRARIES}") + # if pkg-config is used: these variables are empty + # the pkg_search_module call will set the following: + # MAGMA_LDFLAGS: all required linker flags + # MAGMA_CFLAGS: all required cflags + set(MAGMA_INCLUDE_DIRS_DEP "") + set(MAGMA_LIBRARY_DIRS_DEP "") + set(MAGMA_LIBRARIES_DEP "") + # replace it anyway: we should update it with dependencies given by pkg-config + set(MAGMA_INCLUDE_DIRS_DEP "${MAGMA_INCLUDE_DIRS}") + set(MAGMA_LIBRARY_DIRS_DEP "${MAGMA_LIBRARY_DIRS}") + set(MAGMA_LIBRARIES_DEP "${MAGMA_LIBRARIES}") endif(PKG_CONFIG_EXECUTABLE AND NOT MAGMA_GIVEN_BY_USER) # if MAGMA is not found using pkg-config if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT MAGMA_FOUND) OR (MAGMA_GIVEN_BY_USER) ) - if (NOT MAGMA_FIND_QUIETLY) - message(STATUS "Looking for MAGMA - PkgConfig not used") - endif() + if (NOT MAGMA_FIND_QUIETLY) + message(STATUS "Looking for MAGMA - PkgConfig not used") + endif() - # Looking for include - # ------------------- + # Looking for include + # ------------------- - # Add system include paths to search include - # ------------------------------------------ - unset(_inc_env) - set(ENV_MAGMA_DIR "$ENV{MAGMA_DIR}") - set(ENV_MAGMA_INCDIR "$ENV{MAGMA_INCDIR}") - if(ENV_MAGMA_INCDIR) - list(APPEND _inc_env "${ENV_MAGMA_INCDIR}") - elseif(ENV_MAGMA_DIR) - list(APPEND _inc_env "${ENV_MAGMA_DIR}") - list(APPEND _inc_env "${ENV_MAGMA_DIR}/include") - list(APPEND _inc_env "${ENV_MAGMA_DIR}/include/magma") + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + set(ENV_MAGMA_DIR "$ENV{MAGMA_DIR}") + set(ENV_MAGMA_INCDIR "$ENV{MAGMA_INCDIR}") + if(ENV_MAGMA_INCDIR) + list(APPEND _inc_env "${ENV_MAGMA_INCDIR}") + elseif(ENV_MAGMA_DIR) + list(APPEND _inc_env "${ENV_MAGMA_DIR}") + list(APPEND _inc_env "${ENV_MAGMA_DIR}/include") + list(APPEND _inc_env "${ENV_MAGMA_DIR}/include/magma") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") endif() - list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") - list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") - list(REMOVE_DUPLICATES _inc_env) + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) - # Try to find the magma header in the given paths - # ------------------------------------------------- - # call cmake macro to find the header path - if(MAGMA_INCDIR) - set(MAGMA_magma.h_DIRS "MAGMA_magma.h_DIRS-NOTFOUND") - find_path(MAGMA_magma.h_DIRS - NAMES magma.h - HINTS ${MAGMA_INCDIR}) + # Try to find the magma header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(MAGMA_INCDIR) + set(MAGMA_magma.h_DIRS "MAGMA_magma.h_DIRS-NOTFOUND") + find_path(MAGMA_magma.h_DIRS + NAMES magma.h + HINTS ${MAGMA_INCDIR}) + else() + if(MAGMA_DIR) + set(MAGMA_magma.h_DIRS "MAGMA_magma.h_DIRS-NOTFOUND") + find_path(MAGMA_magma.h_DIRS + NAMES magma.h + HINTS ${MAGMA_DIR} + PATH_SUFFIXES "include" "include/magma") else() - if(MAGMA_DIR) - set(MAGMA_magma.h_DIRS "MAGMA_magma.h_DIRS-NOTFOUND") - find_path(MAGMA_magma.h_DIRS - NAMES magma.h - HINTS ${MAGMA_DIR} - PATH_SUFFIXES "include" "include/magma") - else() - set(MAGMA_magma.h_DIRS "MAGMA_magma.h_DIRS-NOTFOUND") - find_path(MAGMA_magma.h_DIRS - NAMES magma.h - HINTS ${_inc_env}) - endif() + set(MAGMA_magma.h_DIRS "MAGMA_magma.h_DIRS-NOTFOUND") + find_path(MAGMA_magma.h_DIRS + NAMES magma.h + HINTS ${_inc_env}) endif() - mark_as_advanced(MAGMA_magma.h_DIRS) + endif() + mark_as_advanced(MAGMA_magma.h_DIRS) - # If found, add path to cmake variable - # ------------------------------------ - if (MAGMA_magma.h_DIRS) - set(MAGMA_INCLUDE_DIRS "${MAGMA_magma.h_DIRS}") - else () - set(MAGMA_INCLUDE_DIRS "MAGMA_INCLUDE_DIRS-NOTFOUND") - if(NOT MAGMA_FIND_QUIETLY) - message(STATUS "Looking for magma -- magma.h not found") - endif() + # If found, add path to cmake variable + # ------------------------------------ + if (MAGMA_magma.h_DIRS) + set(MAGMA_INCLUDE_DIRS "${MAGMA_magma.h_DIRS}") + else () + set(MAGMA_INCLUDE_DIRS "MAGMA_INCLUDE_DIRS-NOTFOUND") + if(NOT MAGMA_FIND_QUIETLY) + message(STATUS "Looking for magma -- magma.h not found") endif() + endif() - # Looking for lib - # --------------- + # Looking for lib + # --------------- - # Add system library paths to search lib - # -------------------------------------- - unset(_lib_env) - set(ENV_MAGMA_LIBDIR "$ENV{MAGMA_LIBDIR}") - if(ENV_MAGMA_LIBDIR) - list(APPEND _lib_env "${ENV_MAGMA_LIBDIR}") - elseif(ENV_MAGMA_DIR) - list(APPEND _lib_env "${ENV_MAGMA_DIR}") - list(APPEND _lib_env "${ENV_MAGMA_DIR}/lib") + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_MAGMA_LIBDIR "$ENV{MAGMA_LIBDIR}") + if(ENV_MAGMA_LIBDIR) + list(APPEND _lib_env "${ENV_MAGMA_LIBDIR}") + elseif(ENV_MAGMA_DIR) + list(APPEND _lib_env "${ENV_MAGMA_DIR}") + list(APPEND _lib_env "${ENV_MAGMA_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") endif() - list(REMOVE_DUPLICATES _lib_env) + endif() + list(REMOVE_DUPLICATES _lib_env) - # Try to find the magma lib in the given paths - # ---------------------------------------------- + # Try to find the magma lib in the given paths + # ---------------------------------------------- - # call cmake macro to find the lib path - if(MAGMA_LIBDIR) - set(MAGMA_magma_LIBRARY "MAGMA_magma_LIBRARY-NOTFOUND") - find_library(MAGMA_magma_LIBRARY - NAMES magma - HINTS ${MAGMA_LIBDIR}) + # call cmake macro to find the lib path + if(MAGMA_LIBDIR) + set(MAGMA_magma_LIBRARY "MAGMA_magma_LIBRARY-NOTFOUND") + find_library(MAGMA_magma_LIBRARY + NAMES magma + HINTS ${MAGMA_LIBDIR}) + else() + if(MAGMA_DIR) + set(MAGMA_magma_LIBRARY "MAGMA_magma_LIBRARY-NOTFOUND") + find_library(MAGMA_magma_LIBRARY + NAMES magma + HINTS ${MAGMA_DIR} + PATH_SUFFIXES lib lib32 lib64) else() - if(MAGMA_DIR) - set(MAGMA_magma_LIBRARY "MAGMA_magma_LIBRARY-NOTFOUND") - find_library(MAGMA_magma_LIBRARY - NAMES magma - HINTS ${MAGMA_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(MAGMA_magma_LIBRARY "MAGMA_magma_LIBRARY-NOTFOUND") - find_library(MAGMA_magma_LIBRARY - NAMES magma - HINTS ${_lib_env}) - endif() + set(MAGMA_magma_LIBRARY "MAGMA_magma_LIBRARY-NOTFOUND") + find_library(MAGMA_magma_LIBRARY + NAMES magma + HINTS ${_lib_env}) endif() - mark_as_advanced(MAGMA_magma_LIBRARY) + endif() + mark_as_advanced(MAGMA_magma_LIBRARY) - # If found, add path to cmake variable - # ------------------------------------ - if (MAGMA_magma_LIBRARY) - get_filename_component(magma_lib_path "${MAGMA_magma_LIBRARY}" PATH) - # set cmake variables - set(MAGMA_LIBRARIES "${MAGMA_magma_LIBRARY}") - set(MAGMA_LIBRARY_DIRS "${magma_lib_path}") - else () - set(MAGMA_LIBRARIES "MAGMA_LIBRARIES-NOTFOUND") - set(MAGMA_LIBRARY_DIRS "MAGMA_LIBRARY_DIRS-NOTFOUND") - if(NOT MAGMA_FIND_QUIETLY) - message(STATUS "Looking for magma -- lib magma not found") - endif() - endif () + # If found, add path to cmake variable + # ------------------------------------ + if (MAGMA_magma_LIBRARY) + get_filename_component(magma_lib_path "${MAGMA_magma_LIBRARY}" PATH) + # set cmake variables + set(MAGMA_LIBRARIES "${MAGMA_magma_LIBRARY}") + set(MAGMA_LIBRARY_DIRS "${magma_lib_path}") + else () + set(MAGMA_LIBRARIES "MAGMA_LIBRARIES-NOTFOUND") + set(MAGMA_LIBRARY_DIRS "MAGMA_LIBRARY_DIRS-NOTFOUND") + if(NOT MAGMA_FIND_QUIETLY) + message(STATUS "Looking for magma -- lib magma not found") + endif() + endif () - # check a function to validate the find - if (MAGMA_LIBRARIES) + # check a function to validate the find + if (MAGMA_LIBRARIES) - set(REQUIRED_LDFLAGS) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) + set(REQUIRED_LDFLAGS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) - # MAGMA - if (MAGMA_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${MAGMA_INCLUDE_DIRS}") - endif() - if (MAGMA_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${MAGMA_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${MAGMA_LIBRARIES}") - # CBLAS - if (CBLAS_INCLUDE_DIRS_DEP) - list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS_DEP}") - elseif (CBLAS_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS}") - endif() - if(CBLAS_LIBRARY_DIRS_DEP) - list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS_DEP}") - elseif(CBLAS_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS}") - endif() - if (CBLAS_LIBRARIES_DEP) - list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES_DEP}") - elseif(CBLAS_LIBRARIES) - list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES}") - endif() - if (BLAS_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") - endif() - # LAPACK - if (LAPACK_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${LAPACK_INCLUDE_DIRS}") - endif() - if(LAPACK_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${LAPACK_LIBRARY_DIRS}") - endif() - list(APPEND REQUIRED_LIBS "${LAPACK_LIBRARIES}") - if (LAPACK_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") - endif() - # CUDA - if (CUDA_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${CUDA_INCLUDE_DIRS}") - endif() - if(CUDA_LIBRARY_DIRS) - list(APPEND REQUIRED_LIBDIRS "${CUDA_LIBRARY_DIRS}") - endif() - list(APPEND REQUIRED_LIBS "${CUDA_CUBLAS_LIBRARIES};${CUDA_LIBRARIES}") + # MAGMA + if (MAGMA_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${MAGMA_INCLUDE_DIRS}") + endif() + if (MAGMA_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${MAGMA_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${MAGMA_LIBRARIES}") + # CBLAS + if (CBLAS_INCLUDE_DIRS_DEP) + list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS_DEP}") + elseif (CBLAS_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${CBLAS_INCLUDE_DIRS}") + endif() + if(CBLAS_LIBRARY_DIRS_DEP) + list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS_DEP}") + elseif(CBLAS_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${CBLAS_LIBRARY_DIRS}") + endif() + if (CBLAS_LIBRARIES_DEP) + list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES_DEP}") + elseif(CBLAS_LIBRARIES) + list(APPEND REQUIRED_LIBS "${CBLAS_LIBRARIES}") + endif() + if (BLAS_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") + endif() + # LAPACK + if (LAPACK_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${LAPACK_INCLUDE_DIRS}") + endif() + if(LAPACK_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${LAPACK_LIBRARY_DIRS}") + endif() + list(APPEND REQUIRED_LIBS "${LAPACK_LIBRARIES}") + if (LAPACK_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${LAPACK_LINKER_FLAGS}") + endif() + # CUDA + if (CUDA_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${CUDA_INCLUDE_DIRS}") + endif() + if(CUDA_LIBRARY_DIRS) + list(APPEND REQUIRED_LIBDIRS "${CUDA_LIBRARY_DIRS}") + endif() + list(APPEND REQUIRED_LIBS "${CUDA_CUBLAS_LIBRARIES};${CUDA_LIBRARIES}") - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - # test link - unset(MAGMA_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(magma_dgetrf MAGMA_WORKS) - mark_as_advanced(MAGMA_WORKS) + # test link + unset(MAGMA_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(magma_dgetrf MAGMA_WORKS) + mark_as_advanced(MAGMA_WORKS) - if(MAGMA_WORKS) - # save link with dependencies - set(MAGMA_LIBRARIES_DEP "${REQUIRED_LIBS}") - set(MAGMA_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") - set(MAGMA_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") - set(MAGMA_LINKER_FLAGS "${REQUIRED_LDFLAGS}") - list(REMOVE_DUPLICATES MAGMA_LIBRARY_DIRS_DEP) - list(REMOVE_DUPLICATES MAGMA_INCLUDE_DIRS_DEP) - list(REMOVE_DUPLICATES MAGMA_LINKER_FLAGS) - else() - if(NOT MAGMA_FIND_QUIETLY) - message(STATUS "Looking for magma : test of magma_dgetrf with - magma, cblas, cuda and lapack libraries fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) - endif(MAGMA_LIBRARIES) + if(MAGMA_WORKS) + # save link with dependencies + set(MAGMA_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(MAGMA_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(MAGMA_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(MAGMA_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES MAGMA_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES MAGMA_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES MAGMA_LINKER_FLAGS) + else() + if(NOT MAGMA_FIND_QUIETLY) + message(STATUS "Looking for magma : test of magma_dgetrf with + magma, cblas, cuda and lapack libraries fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(MAGMA_LIBRARIES) endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT MAGMA_FOUND) OR (MAGMA_GIVEN_BY_USER) ) if (MAGMA_LIBRARIES) - if (MAGMA_LIBRARY_DIRS) - foreach(dir ${MAGMA_LIBRARY_DIRS}) - if ("${dir}" MATCHES "magma") - set(first_lib_path "${dir}") - endif() - endforeach() - else() - list(GET MAGMA_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - endif() - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(MAGMA_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of MAGMA library" FORCE) - else() - set(MAGMA_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of MAGMA library" FORCE) - endif() + if (MAGMA_LIBRARY_DIRS) + foreach(dir ${MAGMA_LIBRARY_DIRS}) + if ("${dir}" MATCHES "magma") + set(first_lib_path "${dir}") + endif() + endforeach() + else() + list(GET MAGMA_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(MAGMA_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of MAGMA library" FORCE) + else() + set(MAGMA_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of MAGMA library" FORCE) + endif() endif() +mark_as_advanced(MAGMA_DIR) +mark_as_advanced(MAGMA_DIR_FOUND) # check that MAGMA has been found # ------------------------------- include(FindPackageHandleStandardArgs) if (PKG_CONFIG_EXECUTABLE AND MAGMA_FOUND) - find_package_handle_standard_args(MAGMA DEFAULT_MSG - MAGMA_LIBRARIES) + find_package_handle_standard_args(MAGMA DEFAULT_MSG + MAGMA_LIBRARIES) else() - find_package_handle_standard_args(MAGMA DEFAULT_MSG - MAGMA_LIBRARIES - MAGMA_WORKS) + find_package_handle_standard_args(MAGMA DEFAULT_MSG + MAGMA_LIBRARIES + MAGMA_WORKS) endif() diff --git a/CMakeModules/morse/find/FindMETIS.cmake b/CMakeModules/morse/find/FindMETIS.cmake index 82a638963dcfe69f86fc855fd6b23056c7942810..da2f1f1d7b056f97a185b9da672bfc2cd4cbb220 100644 --- a/CMakeModules/morse/find/FindMETIS.cmake +++ b/CMakeModules/morse/find/FindMETIS.cmake @@ -47,10 +47,10 @@ # License text for the above reference.) if (NOT METIS_FOUND) - set(METIS_DIR "" CACHE PATH "Installation directory of METIS library") - if (NOT METIS_FIND_QUIETLY) - message(STATUS "A cache variable, namely METIS_DIR, has been set to specify the install directory of METIS") - endif() + set(METIS_DIR "" CACHE PATH "Installation directory of METIS library") + if (NOT METIS_FIND_QUIETLY) + message(STATUS "A cache variable, namely METIS_DIR, has been set to specify the install directory of METIS") + endif() endif() # Looking for include @@ -62,24 +62,24 @@ unset(_inc_env) set(ENV_METIS_DIR "$ENV{METIS_DIR}") set(ENV_METIS_INCDIR "$ENV{METIS_INCDIR}") if(ENV_METIS_INCDIR) - list(APPEND _inc_env "${ENV_METIS_INCDIR}") + list(APPEND _inc_env "${ENV_METIS_INCDIR}") elseif(ENV_METIS_DIR) - list(APPEND _inc_env "${ENV_METIS_DIR}") - list(APPEND _inc_env "${ENV_METIS_DIR}/include") - list(APPEND _inc_env "${ENV_METIS_DIR}/include/metis") + list(APPEND _inc_env "${ENV_METIS_DIR}") + list(APPEND _inc_env "${ENV_METIS_DIR}/include") + list(APPEND _inc_env "${ENV_METIS_DIR}/include/metis") else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() endif() list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") @@ -90,23 +90,23 @@ list(REMOVE_DUPLICATES _inc_env) # ------------------------------------------------- # call cmake macro to find the header path if(METIS_INCDIR) + set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND") + find_path(METIS_metis.h_DIRS + NAMES metis.h + HINTS ${METIS_INCDIR}) +else() + if(METIS_DIR) set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND") find_path(METIS_metis.h_DIRS NAMES metis.h - HINTS ${METIS_INCDIR}) -else() - if(METIS_DIR) - set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND") - find_path(METIS_metis.h_DIRS - NAMES metis.h - HINTS ${METIS_DIR} - PATH_SUFFIXES "include" "include/metis") - else() - set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND") - find_path(METIS_metis.h_DIRS - NAMES metis.h - HINTS ${_inc_env}) - endif() + HINTS ${METIS_DIR} + PATH_SUFFIXES "include" "include/metis") + else() + set(METIS_metis.h_DIRS "METIS_metis.h_DIRS-NOTFOUND") + find_path(METIS_metis.h_DIRS + NAMES metis.h + HINTS ${_inc_env}) + endif() endif() mark_as_advanced(METIS_metis.h_DIRS) @@ -114,12 +114,12 @@ mark_as_advanced(METIS_metis.h_DIRS) # If found, add path to cmake variable # ------------------------------------ if (METIS_metis.h_DIRS) - set(METIS_INCLUDE_DIRS "${METIS_metis.h_DIRS}") + set(METIS_INCLUDE_DIRS "${METIS_metis.h_DIRS}") else () - set(METIS_INCLUDE_DIRS "METIS_INCLUDE_DIRS-NOTFOUND") - if(NOT METIS_FIND_QUIETLY) - message(STATUS "Looking for metis -- metis.h not found") - endif() + set(METIS_INCLUDE_DIRS "METIS_INCLUDE_DIRS-NOTFOUND") + if(NOT METIS_FIND_QUIETLY) + message(STATUS "Looking for metis -- metis.h not found") + endif() endif() @@ -131,22 +131,22 @@ endif() unset(_lib_env) set(ENV_METIS_LIBDIR "$ENV{METIS_LIBDIR}") if(ENV_METIS_LIBDIR) - list(APPEND _lib_env "${ENV_METIS_LIBDIR}") + list(APPEND _lib_env "${ENV_METIS_LIBDIR}") elseif(ENV_METIS_DIR) - list(APPEND _lib_env "${ENV_METIS_DIR}") - list(APPEND _lib_env "${ENV_METIS_DIR}/lib") + list(APPEND _lib_env "${ENV_METIS_DIR}") + list(APPEND _lib_env "${ENV_METIS_DIR}/lib") else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() endif() list(REMOVE_DUPLICATES _lib_env) @@ -154,23 +154,23 @@ list(REMOVE_DUPLICATES _lib_env) # ---------------------------------------------- # call cmake macro to find the lib path if(METIS_LIBDIR) + set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND") + find_library(METIS_metis_LIBRARY + NAMES metis + HINTS ${METIS_LIBDIR}) +else() + if(METIS_DIR) set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND") find_library(METIS_metis_LIBRARY - NAMES metis - HINTS ${METIS_LIBDIR}) -else() - if(METIS_DIR) - set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND") - find_library(METIS_metis_LIBRARY - NAMES metis - HINTS ${METIS_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND") - find_library(METIS_metis_LIBRARY - NAMES metis - HINTS ${_lib_env}) - endif() + NAMES metis + HINTS ${METIS_DIR} + PATH_SUFFIXES lib lib32 lib64) + else() + set(METIS_metis_LIBRARY "METIS_metis_LIBRARY-NOTFOUND") + find_library(METIS_metis_LIBRARY + NAMES metis + HINTS ${_lib_env}) + endif() endif() mark_as_advanced(METIS_metis_LIBRARY) @@ -178,84 +178,87 @@ mark_as_advanced(METIS_metis_LIBRARY) # If found, add path to cmake variable # ------------------------------------ if (METIS_metis_LIBRARY) - get_filename_component(metis_lib_path "${METIS_metis_LIBRARY}" PATH) - # set cmake variables - set(METIS_LIBRARIES "${METIS_metis_LIBRARY}") - set(METIS_LIBRARY_DIRS "${metis_lib_path}") + get_filename_component(metis_lib_path "${METIS_metis_LIBRARY}" PATH) + # set cmake variables + set(METIS_LIBRARIES "${METIS_metis_LIBRARY}") + set(METIS_LIBRARY_DIRS "${metis_lib_path}") else () - set(METIS_LIBRARIES "METIS_LIBRARIES-NOTFOUND") - set(METIS_LIBRARY_DIRS "METIS_LIBRARY_DIRS-NOTFOUND") - if(NOT METIS_FIND_QUIETLY) - message(STATUS "Looking for metis -- lib metis not found") - endif() + set(METIS_LIBRARIES "METIS_LIBRARIES-NOTFOUND") + set(METIS_LIBRARY_DIRS "METIS_LIBRARY_DIRS-NOTFOUND") + if(NOT METIS_FIND_QUIETLY) + message(STATUS "Looking for metis -- lib metis not found") + endif() endif () # check a function to validate the find if(METIS_LIBRARIES) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) - # METIS - if (METIS_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}") - endif() - if (METIS_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${METIS_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${METIS_LIBRARIES}") - # m - find_library(M_LIBRARY NAMES m) - if(M_LIBRARY) - list(APPEND REQUIRED_LIBS "-lm") - endif() + # METIS + if (METIS_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}") + endif() + if (METIS_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${METIS_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${METIS_LIBRARIES}") + # m + find_library(M_LIBRARY NAMES m) + mark_as_advanced(M_LIBRARY) + if(M_LIBRARY) + list(APPEND REQUIRED_LIBS "-lm") + endif() - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - # test link - unset(METIS_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(METIS_NodeND METIS_WORKS) - mark_as_advanced(METIS_WORKS) + # test link + unset(METIS_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(METIS_NodeND METIS_WORKS) + mark_as_advanced(METIS_WORKS) - if(NOT METIS_WORKS) - if(NOT METIS_FIND_QUIETLY) - message(STATUS "Looking for METIS : test of METIS_NodeND with METIS library fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - endif() + if(NOT METIS_WORKS) + if(NOT METIS_FIND_QUIETLY) + message(STATUS "Looking for METIS : test of METIS_NodeND with METIS library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) endif(METIS_LIBRARIES) if (METIS_LIBRARIES) - list(GET METIS_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(METIS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of METIS library" FORCE) - else() - set(METIS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of METIS library" FORCE) - endif() + list(GET METIS_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(METIS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of METIS library" FORCE) + else() + set(METIS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of METIS library" FORCE) + endif() endif() +mark_as_advanced(METIS_DIR) +mark_as_advanced(METIS_DIR_FOUND) # check that METIS has been found # --------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(METIS DEFAULT_MSG - METIS_LIBRARIES - METIS_WORKS) + METIS_LIBRARIES + METIS_WORKS) # # TODO: Add possibility to check for specific functions in the library # diff --git a/CMakeModules/morse/find/FindMPIEXT.cmake b/CMakeModules/morse/find/FindMPIEXT.cmake index 68520a478eb4bef8943830a93830a73994b3ad07..1409989751594a714a0d4d17a23adb194aff356e 100644 --- a/CMakeModules/morse/find/FindMPIEXT.cmake +++ b/CMakeModules/morse/find/FindMPIEXT.cmake @@ -23,11 +23,11 @@ # add a cache variable to let the user specify the BLAS vendor if (NOT MPI_FOUND) - if(MPIEXT_FIND_REQUIRED) - find_package(MPI REQUIRED) - else() - find_package(MPI) - endif() + if(MPIEXT_FIND_REQUIRED) + find_package(MPI REQUIRED) + else() + find_package(MPI) + endif() endif () if (MPI_FOUND) @@ -103,9 +103,9 @@ int main(int argc, char **argv) { if(NOT SERIALIZED_TEST_RUNS) check_c_source_runs("${MPI_C_TEST_FUNNELED_SOURCE}" FUNNELED_TEST_RUNS) if(NOT FUNNELED_TEST_RUNS) - set(MPI_THREAD_SUPPORTED_LEVEL "MPI_THREAD_SINGLE") + set(MPI_THREAD_SUPPORTED_LEVEL "MPI_THREAD_SINGLE") else(NOT FUNNELED_TEST_RUNS) - set(MPI_THREAD_SUPPORTED_LEVEL "MPI_THREAD_FUNNELED") + set(MPI_THREAD_SUPPORTED_LEVEL "MPI_THREAD_FUNNELED") endif(NOT FUNNELED_TEST_RUNS) else(NOT SERIALIZED_TEST_RUNS) set(MPI_THREAD_SUPPORTED_LEVEL "MPI_THREAD_SERIALIZED") @@ -117,4 +117,4 @@ int main(int argc, char **argv) { set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_SAVE}) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_SAVE}) set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE}) -endif(MPI_FOUND) \ No newline at end of file +endif(MPI_FOUND) diff --git a/CMakeModules/morse/find/FindMUMPS.cmake b/CMakeModules/morse/find/FindMUMPS.cmake index 7e7afe7e0b2876dfb57d2cc8b5b2213fb067107e..4c956e85acee833a17a88045c8689d6cc9a533be 100644 --- a/CMakeModules/morse/find/FindMUMPS.cmake +++ b/CMakeModules/morse/find/FindMUMPS.cmake @@ -27,7 +27,9 @@ # - SEQ: to activate detection of sequential version (exclude MPI version) # it looks for Threads and BLAS libraries # - SCOTCH: to activate detection of MUMPS linked with SCOTCH +# - PTSCOTCH: to activate detection of MUMPS linked with PTSCOTCH # - METIS: to activate detection of MUMPS linked with METIS +# - PARMETIS: to activate detection of MUMPS linked with PARMETIS # # This module finds headers and mumps library. # Results are reported in variables: @@ -65,109 +67,90 @@ if (NOT MUMPS_FOUND) - set(MUMPS_DIR "" CACHE PATH "Installation directory of MUMPS library") - if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "A cache variable, namely MUMPS_DIR, has been set to specify the install directory of MUMPS") - endif() + set(MUMPS_DIR "" CACHE PATH "Installation directory of MUMPS library") + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "A cache variable, namely MUMPS_DIR, has been set to specify the install directory of MUMPS") + endif() endif() # Set the version to find set(MUMPS_LOOK_FOR_MPI ON) set(MUMPS_LOOK_FOR_SEQ OFF) set(MUMPS_LOOK_FOR_SCOTCH OFF) +set(MUMPS_LOOK_FOR_PTSCOTCH OFF) set(MUMPS_LOOK_FOR_METIS OFF) +set(MUMPS_LOOK_FOR_PARMETIS OFF) if( MUMPS_FIND_COMPONENTS ) - foreach( component ${MUMPS_FIND_COMPONENTS} ) - if (${component} STREQUAL "SEQ") - # means we look for the sequential version of MUMPS (without MPI) - set(MUMPS_LOOK_FOR_SEQ ON) - set(MUMPS_LOOK_FOR_MPI OFF) - endif() - if (${component} STREQUAL "MPI") - # means we look for the MPI version of MUMPS (default) - set(MUMPS_LOOK_FOR_MPI ON) - set(MUMPS_LOOK_FOR_SEQ OFF) - endif() - if (${component} STREQUAL "SCOTCH") - set(MUMPS_LOOK_FOR_SCOTCH ON) - endif() - if (${component} STREQUAL "METIS") - set(MUMPS_LOOK_FOR_METIS ON) - endif() - endforeach() -endif() - -if (NOT MUMPS_FIND_QUIETLY) - if (MUMPS_LOOK_FOR_SEQ) - message(STATUS "Looking for MUMPS - sequential version (without MPI)") - else() - message(STATUS "Looking for MUMPS - MPI version -" - " if you want to force detection of a sequential " - "version use find_package(MUMPS [REQUIRED] COMPONENTS SEQ [...])") + foreach( component ${MUMPS_FIND_COMPONENTS} ) + if (${component} STREQUAL "SEQ") + # means we look for the sequential version of MUMPS (without MPI) + set(MUMPS_LOOK_FOR_SEQ ON) + set(MUMPS_LOOK_FOR_MPI OFF) + endif() + if (${component} STREQUAL "MPI") + # means we look for the MPI version of MUMPS (default) + set(MUMPS_LOOK_FOR_MPI ON) + set(MUMPS_LOOK_FOR_SEQ OFF) + endif() + if (${component} STREQUAL "SCOTCH") + set(MUMPS_LOOK_FOR_SCOTCH ON) endif() + if (${component} STREQUAL "PTSCOTCH") + set(MUMPS_LOOK_FOR_PTSCOTCH ON) + endif() + if (${component} STREQUAL "METIS") + set(MUMPS_LOOK_FOR_METIS ON) + endif() + if (${component} STREQUAL "PARMETIS") + set(MUMPS_LOOK_FOR_PARMETIS ON) + endif() + endforeach() endif() if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - PkgConfig not used") + if (MUMPS_LOOK_FOR_SEQ) + message(STATUS "Looking for MUMPS - sequential version (without MPI)") + else() + message(STATUS "Looking for MUMPS - MPI version -" + " if you want to force detection of a sequential " + "version use find_package(MUMPS [REQUIRED] COMPONENTS SEQ [...])") + endif() endif() -# Dependencies detection -# ---------------------- - -# Add system library paths to search lib -# -------------------------------------- -unset(_lib_env) -set(ENV_MUMPS_LIBDIR "$ENV{MUMPS_LIBDIR}") -if(ENV_MUMPS_LIBDIR) - list(APPEND _lib_env "${ENV_MUMPS_LIBDIR}") -elseif(ENV_MUMPS_DIR) - list(APPEND _lib_env "${ENV_MUMPS_DIR}") - list(APPEND _lib_env "${ENV_MUMPS_DIR}/lib") -else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") - else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") - endif() +if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - PkgConfig not used") endif() -list(REMOVE_DUPLICATES _lib_env) # Required dependencies # --------------------- if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - Try to detect pthread") + message(STATUS "Looking for MUMPS - Try to detect pthread") endif() if (NOT Threads_FOUND) - if (MUMPS_FIND_REQUIRED) - find_package(Threads REQUIRED) - else() - find_package(Threads) - endif() + if (MUMPS_FIND_REQUIRED) + find_package(Threads REQUIRED) + else() + find_package(Threads) + endif() endif() set(MUMPS_EXTRA_LIBRARIES "") if( THREADS_FOUND ) - list(APPEND MUMPS_EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + list(APPEND MUMPS_EXTRA_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) endif () # MUMPS depends on BLAS #---------------------- if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - Try to detect BLAS") + message(STATUS "Looking for MUMPS - Try to detect BLAS") endif() if (NOT BLASEXT_FOUND) - if (MUMPS_FIND_REQUIRED) - find_package(BLASEXT REQUIRED) - else() - find_package(BLASEXT) - endif() + if (MUMPS_FIND_REQUIRED) + find_package(BLASEXT REQUIRED) + else() + find_package(BLASEXT) + endif() endif() # Optional dependencies @@ -176,211 +159,275 @@ endif() # MUMPS may depend on MPI #------------------------ if (NOT MPI_FOUND AND MUMPS_LOOK_FOR_MPI) - if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - Try to detect MPI") - endif() - # allows to use an external mpi compilation by setting compilers with - # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90 - # at cmake configure - if(NOT MPI_C_COMPILER) - set(MPI_C_COMPILER mpicc) - endif() - if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_MPI) - find_package(MPI REQUIRED) - else() - find_package(MPI) - endif() - if (MPI_FOUND) - mark_as_advanced(MPI_LIBRARY) - mark_as_advanced(MPI_EXTRA_LIBRARY) - endif() + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - Try to detect MPI") + endif() + # allows to use an external mpi compilation by setting compilers with + # -DMPI_C_COMPILER=path/to/mpicc -DMPI_Fortran_COMPILER=path/to/mpif90 + # at cmake configure + if(NOT MPI_C_COMPILER) + set(MPI_C_COMPILER mpicc) + endif() + if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_MPI) + find_package(MPI REQUIRED) + else() + find_package(MPI) + endif() + if (MPI_FOUND) + mark_as_advanced(MPI_LIBRARY) + mark_as_advanced(MPI_EXTRA_LIBRARY) + endif() endif (NOT MPI_FOUND AND MUMPS_LOOK_FOR_MPI) # MUMPS may depend on ScaLAPACK (if MPI version) #----------------------------------------------- if (NOT SCALAPACK_FOUND AND MUMPS_LOOK_FOR_MPI) - if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - Try to detect SCALAPACK") - endif() - # SCALAPACK is a required dependency if MPI is used - if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_MPI) - find_package(SCALAPACK REQUIRED) - else() - find_package(SCALAPACK) - endif() + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - Try to detect SCALAPACK") + endif() + # SCALAPACK is a required dependency if MPI is used + if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_MPI) + find_package(SCALAPACK REQUIRED) + else() + find_package(SCALAPACK) + endif() endif (NOT SCALAPACK_FOUND AND MUMPS_LOOK_FOR_MPI) # MUMPS may depends on SCOTCH #---------------------------- -if (NOT SCOTCH_FOUND AND MUMPS_LOOK_FOR_SCOTCH) - if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - Try to detect SCOTCH") - endif() - if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_SCOTCH) - find_package(SCOTCH REQUIRED) - else() - find_package(SCOTCH) - endif() +if (MUMPS_LOOK_FOR_SCOTCH) + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - Try to detect SCOTCH with esmumps") + endif() + if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_SCOTCH) + find_package(SCOTCH REQUIRED COMPONENTS ESMUMPS) + else() + find_package(SCOTCH COMPONENTS ESMUMPS) + endif() +endif() + +# MUMPS may depends on PTSCOTCH +#------------------------------ +if (MUMPS_LOOK_FOR_PTSCOTCH) + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - Try to detect PTSCOTCH with esmumps") + endif() + if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_PTSCOTCH) + find_package(PTSCOTCH REQUIRED COMPONENTS ESMUMPS) + else() + find_package(PTSCOTCH COMPONENTS ESMUMPS) + endif() endif() # MUMPS may depends on METIS #--------------------------- if (NOT METIS_FOUND AND MUMPS_LOOK_FOR_METIS) - if (NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS - Try to detect METIS") - endif() - if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_METIS) - find_package(METIS REQUIRED) - else() - find_package(METIS) - endif() + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - Try to detect METIS") + endif() + if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_METIS) + find_package(METIS REQUIRED) + else() + find_package(METIS) + endif() endif() +# MUMPS may depends on PARMETIS +#------------------------------ +if (NOT PARMETIS_FOUND AND MUMPS_LOOK_FOR_PARMETIS) + if (NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS - Try to detect PARMETIS") + endif() + if (MUMPS_FIND_REQUIRED AND MUMPS_FIND_REQUIRED_PARMETIS) + find_package(PARMETIS REQUIRED) + else() + find_package(PARMETIS) + endif() +endif() # Looking for MUMPS # ----------------- +# Add system include paths to search include +# ------------------------------------------ +unset(_inc_env) +set(ENV_MUMPS_DIR "$ENV{MUMPS_DIR}") +set(ENV_MUMPS_INCDIR "$ENV{MUMPS_INCDIR}") +if(ENV_MUMPS_INCDIR) + list(APPEND _inc_env "${ENV_MUMPS_INCDIR}") +elseif(ENV_MUMPS_DIR) + list(APPEND _inc_env "${ENV_MUMPS_DIR}") + list(APPEND _inc_env "${ENV_MUMPS_DIR}/include") + list(APPEND _inc_env "${ENV_MUMPS_DIR}/include/mumps") +else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() +endif() +list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") +list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") +list(REMOVE_DUPLICATES _inc_env) + +# Add system library paths to search lib +# -------------------------------------- +unset(_lib_env) +set(ENV_MUMPS_LIBDIR "$ENV{MUMPS_LIBDIR}") +if(ENV_MUMPS_LIBDIR) + list(APPEND _lib_env "${ENV_MUMPS_LIBDIR}") +elseif(ENV_MUMPS_DIR) + list(APPEND _lib_env "${ENV_MUMPS_DIR}") + list(APPEND _lib_env "${ENV_MUMPS_DIR}/lib") +else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() +endif() +list(REMOVE_DUPLICATES _lib_env) + # Looking for include # ------------------- # Try to find the mumps header in the given path # ---------------------------------------------- + +# create list of headers to find +list(APPEND MUMPS_hdrs_to_find "smumps_c.h;dmumps_c.h;cmumps_c.h;zmumps_c.h") + # call cmake macro to find the header path -if(MUMPS_DIR) - set(MUMPS_smumps_c.h_DIRS "MUMPS_smumps_c.h_DIRS-NOTFOUND") - find_path(MUMPS_smumps_c.h_DIRS - NAMES smumps_c.h - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES "include") - set(MUMPS_dmumps_c.h_DIRS "MUMPS_dmumps_c.h_DIRS-NOTFOUND") - find_path(MUMPS_dmumps_c.h_DIRS - NAMES dmumps_c.h - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES "include") - set(MUMPS_cmumps_c.h_DIRS "MUMPS_cmumps_c.h_DIRS-NOTFOUND") - find_path(MUMPS_cmumps_c.h_DIRS - NAMES cmumps_c.h - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES "include") - set(MUMPS_zmumps_c.h_DIRS "MUMPS_zmumps_c.h_DIRS-NOTFOUND") - find_path(MUMPS_zmumps_c.h_DIRS - NAMES zmumps_c.h - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES "include") +if(MUMPS_INCDIR) + foreach(mumps_hdr ${MUMPS_hdrs_to_find}) + set(MUMPS_${mumps_hdr}_DIRS "MUMPS_${mumps_hdr}_INCLUDE_DIRS-NOTFOUND") + find_path(MUMPS_${mumps_hdr}_DIRS + NAMES ${mumps_hdr} + HINTS ${MUMPS_INCDIR}) + endforeach() else() - if (MUMPS_FIND_REQUIRED) - message(FATAL_ERROR "Looking for mumps -- MUMPS_DIR is not set, to find" - " MUMPS please set MUMPS_DIR, the path to MUMPS installation where" - " sub-directories include/ and lib/ are located") - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- MUMPS_DIR is not set, to find" - " MUMPS please set MUMPS_DIR, the path to MUMPS installation where" - " sub-directories include/ and lib/ are located") - endif() - endif() + if(MUMPS_DIR) + set(MUMPS_${mumps_hdr}_DIRS "MUMPS_${mumps_hdr}_INCLUDE_DIRS-NOTFOUND") + foreach(mumps_hdr ${MUMPS_hdrs_to_find}) + find_path(MUMPS_${mumps_hdr}_DIRS + NAMES ${mumps_hdr} + HINTS ${MUMPS_DIR} + PATH_SUFFIXES "include") + endforeach() + else() + foreach(mumps_hdr ${MUMPS_hdrs_to_find}) + set(MUMPS_${mumps_hdr}_DIRS "MUMPS_${mumps_hdr}_INCLUDE_DIRS-NOTFOUND") + find_path(MUMPS_${mumps_hdr}_DIRS + NAMES ${mumps_hdr} + HINTS ${_inc_env}) + endforeach() + endif() endif() # If found, add path to cmake variable # ------------------------------------ # detect which precisions are available if (MUMPS_smumps_c.h_DIRS) - mark_as_advanced(MUMPS_smumps_c.h_DIRS) - set(MUMPS_PREC_S ON) - set(MUMPS_INCLUDE_DIRS "${MUMPS_smumps_c.h_DIRS}") + mark_as_advanced(MUMPS_smumps_c.h_DIRS) + set(MUMPS_PREC_S ON) + set(MUMPS_INCLUDE_DIRS "${MUMPS_smumps_c.h_DIRS}") else () - set(MUMPS_PREC_S OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- smumps_c.h not found") - endif() + set(MUMPS_PREC_S OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- smumps_c.h not found") + endif() endif() if (MUMPS_dmumps_c.h_DIRS) - mark_as_advanced(MUMPS_dmumps_c.h_DIRS) - set(MUMPS_PREC_D ON) - set(MUMPS_INCLUDE_DIRS "${MUMPS_dmumps_c.h_DIRS}") + mark_as_advanced(MUMPS_dmumps_c.h_DIRS) + set(MUMPS_PREC_D ON) + set(MUMPS_INCLUDE_DIRS "${MUMPS_dmumps_c.h_DIRS}") else () - set(MUMPS_PREC_D OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- dmumps_c.h not found") - endif() + set(MUMPS_PREC_D OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- dmumps_c.h not found") + endif() endif() if (MUMPS_cmumps_c.h_DIRS) - mark_as_advanced(MUMPS_cmumps_c.h_DIRS) - set(MUMPS_PREC_C ON) - set(MUMPS_INCLUDE_DIRS "${MUMPS_cmumps_c.h_DIRS}") + mark_as_advanced(MUMPS_cmumps_c.h_DIRS) + set(MUMPS_PREC_C ON) + set(MUMPS_INCLUDE_DIRS "${MUMPS_cmumps_c.h_DIRS}") else () - set(MUMPS_PREC_C OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- cmumps_c.h not found") - endif() + set(MUMPS_PREC_C OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- cmumps_c.h not found") + endif() endif() if (MUMPS_zmumps_c.h_DIRS) - mark_as_advanced(MUMPS_zmumps_c.h_DIRS) - set(MUMPS_PREC_Z ON) - set(MUMPS_INCLUDE_DIRS "${MUMPS_zmumps_c.h_DIRS}") + mark_as_advanced(MUMPS_zmumps_c.h_DIRS) + set(MUMPS_PREC_Z ON) + set(MUMPS_INCLUDE_DIRS "${MUMPS_zmumps_c.h_DIRS}") else () - set(MUMPS_PREC_Z OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- zmumps_c.h not found") - endif() + set(MUMPS_PREC_Z OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- zmumps_c.h not found") + endif() endif() # Looking for lib # --------------- -# Try to find the mumps lib in the given paths -# -------------------------------------------- +# create list of libs to find +set(MUMPS_libs_to_find "mumps_common;pord") +if (MUMPS_LOOK_FOR_SEQ) + list(APPEND MUMPS_libs_to_find "mpiseq") +endif() +if(MUMPS_PREC_S) + list(APPEND MUMPS_libs_to_find "smumps") +endif() +if(MUMPS_PREC_D) + list(APPEND MUMPS_libs_to_find "dmumps") +endif() +if(MUMPS_PREC_C) + list(APPEND MUMPS_libs_to_find "cmumps") +endif() +if(MUMPS_PREC_Z) + list(APPEND MUMPS_libs_to_find "zmumps") +endif() # call cmake macro to find the lib path -if(MUMPS_DIR) - set(MUMPS_smumps_LIBRARY "MUMPS_smumps_LIBRARY-NOTFOUND") - find_library(MUMPS_smumps_LIBRARY - NAMES smumps - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES lib) - set(MUMPS_dmumps_LIBRARY "MUMPS_dmumps_LIBRARY-NOTFOUND") - find_library(MUMPS_dmumps_LIBRARY - NAMES dmumps - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES lib) - set(MUMPS_cmumps_LIBRARY "MUMPS_cmumps_LIBRARY-NOTFOUND") - find_library(MUMPS_cmumps_LIBRARY - NAMES cmumps - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES lib) - set(MUMPS_zmumps_LIBRARY "MUMPS_zmumps_LIBRARY-NOTFOUND") - find_library(MUMPS_zmumps_LIBRARY - NAMES zmumps - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES lib) - set(MUMPS_mumps_common_LIBRARY "MUMPS_mumps_common_LIBRARY-NOTFOUND") - find_library(MUMPS_mumps_common_LIBRARY - NAMES mumps_common - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES lib) - set(MUMPS_mpiseq_LIBRARY "MUMPS_mpiseq_LIBRARY-NOTFOUND") - find_library(MUMPS_mpiseq_LIBRARY - NAMES mpiseq - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES libseq) - set(MUMPS_pord_LIBRARY "MUMPS_pord_LIBRARY-NOTFOUND") - find_library(MUMPS_pord_LIBRARY - NAMES pord - HINTS "${MUMPS_DIR}" "$ENV{MUMPS_DIR}" - PATH_SUFFIXES lib) +if(MUMPS_LIBDIR) + foreach(mumps_lib ${MUMPS_libs_to_find}) + set(MUMPS_${mumps_lib}_LIBRARY "MUMPS_${mumps_lib}_LIBRARY-NOTFOUND") + find_library(MUMPS_${mumps_lib}_LIBRARY + NAMES ${mumps_lib} + HINTS ${MUMPS_LIBDIR}) + endforeach() else() - if (MUMPS_FIND_REQUIRED) - message(FATAL_ERROR "Looking for mumps -- MUMPS_DIR is not set, to find" - " MUMPS please set MUMPS_DIR, the path to MUMPS installation where" - " sub-directories include/ and lib/ are located") - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- MUMPS_DIR is not set, to find" - " MUMPS please set MUMPS_DIR, the path to MUMPS installation where" - " sub-directories include/ and lib/ are located") - endif() - endif() + if(MUMPS_DIR) + foreach(mumps_lib ${MUMPS_libs_to_find}) + set(MUMPS_${mumps_lib}_LIBRARY "MUMPS_${mumps_lib}_LIBRARY-NOTFOUND") + find_library(MUMPS_${mumps_lib}_LIBRARY + NAMES ${mumps_lib} + HINTS ${MUMPS_DIR} + PATH_SUFFIXES lib lib32 lib64) + endforeach() + else() + foreach(mumps_lib ${MUMPS_libs_to_find}) + set(MUMPS_${mumps_lib}_LIBRARY "MUMPS_${mumps_lib}_LIBRARY-NOTFOUND") + find_library(MUMPS_${mumps_lib}_LIBRARY + NAMES ${mumps_lib} + HINTS ${_lib_env}) + endforeach() + endif() endif() # If found, add path to cmake variable @@ -389,109 +436,109 @@ set(MUMPS_LIBRARIES "") set(MUMPS_LIBRARY_DIRS "") # detect which precisions are available if (MUMPS_smumps_LIBRARY) - mark_as_advanced(MUMPS_smumps_LIBRARY) - list(APPEND MUMPS_LIBRARIES "${MUMPS_smumps_LIBRARY}") - get_filename_component(smumps_lib_path ${MUMPS_smumps_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${smumps_lib_path}") + mark_as_advanced(MUMPS_smumps_LIBRARY) + list(APPEND MUMPS_LIBRARIES "${MUMPS_smumps_LIBRARY}") + get_filename_component(smumps_lib_path ${MUMPS_smumps_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${smumps_lib_path}") else () - set(MUMPS_PREC_S OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libsmumps.a not found") - endif() + set(MUMPS_PREC_S OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libsmumps.a not found") + endif() endif() if (MUMPS_dmumps_LIBRARY) - mark_as_advanced(MUMPS_dmumps_LIBRARY) - list(APPEND MUMPS_LIBRARIES "${MUMPS_dmumps_LIBRARY}") - get_filename_component(dmumps_lib_path ${MUMPS_dmumps_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${dmumps_lib_path}") + mark_as_advanced(MUMPS_dmumps_LIBRARY) + list(APPEND MUMPS_LIBRARIES "${MUMPS_dmumps_LIBRARY}") + get_filename_component(dmumps_lib_path ${MUMPS_dmumps_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${dmumps_lib_path}") else () - set(MUMPS_PREC_D OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libdmumps.a not found") - endif() + set(MUMPS_PREC_D OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libdmumps.a not found") + endif() endif() if (MUMPS_cmumps_LIBRARY) - mark_as_advanced(MUMPS_cmumps_LIBRARY) - list(APPEND MUMPS_LIBRARIES "${MUMPS_cmumps_LIBRARY}") - get_filename_component(cmumps_lib_path ${MUMPS_cmumps_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${cmumps_lib_path}") + mark_as_advanced(MUMPS_cmumps_LIBRARY) + list(APPEND MUMPS_LIBRARIES "${MUMPS_cmumps_LIBRARY}") + get_filename_component(cmumps_lib_path ${MUMPS_cmumps_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${cmumps_lib_path}") else () - set(MUMPS_PREC_C OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libcmumps.a not found") - endif() + set(MUMPS_PREC_C OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libcmumps.a not found") + endif() endif() if (MUMPS_zmumps_LIBRARY) - mark_as_advanced(MUMPS_zmumps_LIBRARY) - list(APPEND MUMPS_LIBRARIES "${MUMPS_zmumps_LIBRARY}") - get_filename_component(zmumps_lib_path ${MUMPS_zmumps_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${zmumps_lib_path}") + mark_as_advanced(MUMPS_zmumps_LIBRARY) + list(APPEND MUMPS_LIBRARIES "${MUMPS_zmumps_LIBRARY}") + get_filename_component(zmumps_lib_path ${MUMPS_zmumps_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${zmumps_lib_path}") else () - set(MUMPS_PREC_Z OFF) - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libzmumps.a not found") - endif() + set(MUMPS_PREC_Z OFF) + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libzmumps.a not found") + endif() endif() # check that one precision arithmetic at least has been discovered if (NOT MUMPS_PREC_S AND NOT MUMPS_PREC_D AND NOT MUMPS_PREC_C AND NOT MUMPS_PREC_S) - if (MUMPS_FIND_REQUIRED) - message(FATAL_ERROR "Looking for mumps -- " - "no lib[sdcz]mumps.a have been found in ${MUMPS_DIR}/lib when required") - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- no lib[sdcz]mumps.a have been found") - endif() + if (MUMPS_FIND_REQUIRED) + message(FATAL_ERROR "Looking for mumps -- " + "no lib[sdcz]mumps.a have been found in ${MUMPS_DIR}/lib when required") + else() + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- no lib[sdcz]mumps.a have been found") endif() + endif() endif() # other MUMPS libraries if (MUMPS_mumps_common_LIBRARY) - mark_as_advanced(MUMPS_mumps_common_LIBRARY) - list(APPEND MUMPS_LIBRARIES "${MUMPS_mumps_common_LIBRARY}") - get_filename_component(mumps_common_lib_path ${MUMPS_mumps_common_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${mumps_common_lib_path}") + mark_as_advanced(MUMPS_mumps_common_LIBRARY) + list(APPEND MUMPS_LIBRARIES "${MUMPS_mumps_common_LIBRARY}") + get_filename_component(mumps_common_lib_path ${MUMPS_mumps_common_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${mumps_common_lib_path}") else () - if (MUMPS_FIND_REQUIRED) - message(FATAL_ERROR "Looking for mumps -- " - "libmumps_common.a not found in ${MUMPS_DIR}/lib when required") - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libmumps_common.a not found") - endif() + if (MUMPS_FIND_REQUIRED) + message(FATAL_ERROR "Looking for mumps -- " + "libmumps_common.a not found in ${MUMPS_DIR}/lib when required") + else() + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libmumps_common.a not found") endif() + endif() endif() if (MUMPS_mpiseq_LIBRARY) - mark_as_advanced(MUMPS_mpiseq_LIBRARY) - if (MUMPS_LOOK_FOR_SEQ) - list(APPEND MUMPS_LIBRARIES "${MUMPS_mpiseq_LIBRARY}") - get_filename_component(mpiseq_lib_path ${MUMPS_mpiseq_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${mpiseq_lib_path}") - list(APPEND MUMPS_INCLUDE_DIRS "${mpiseq_lib_path}") - endif() + mark_as_advanced(MUMPS_mpiseq_LIBRARY) + if (MUMPS_LOOK_FOR_SEQ) + list(APPEND MUMPS_LIBRARIES "${MUMPS_mpiseq_LIBRARY}") + get_filename_component(mpiseq_lib_path ${MUMPS_mpiseq_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${mpiseq_lib_path}") + list(APPEND MUMPS_INCLUDE_DIRS "${mpiseq_lib_path}") + endif() else () - if (MUMPS_FIND_REQUIRED AND MUMPS_LOOK_FOR_SEQ) - message(FATAL_ERROR "Looking for mumps -- " - "libmpiseq.a not found in ${MUMPS_DIR}/libseq when required") - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libmpiseq.a not found") - endif() + if (MUMPS_FIND_REQUIRED AND MUMPS_LOOK_FOR_SEQ) + message(FATAL_ERROR "Looking for mumps -- " + "libmpiseq.a not found in ${MUMPS_DIR}/libseq when required") + else() + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libmpiseq.a not found") endif() + endif() endif() if (MUMPS_pord_LIBRARY) - mark_as_advanced(MUMPS_pord_LIBRARY) - list(APPEND MUMPS_LIBRARIES "${MUMPS_pord_LIBRARY}") - get_filename_component(pord_lib_path ${MUMPS_pord_LIBRARY} PATH) - list(APPEND MUMPS_LIBRARY_DIRS "${pord_lib_path}") + mark_as_advanced(MUMPS_pord_LIBRARY) + list(APPEND MUMPS_LIBRARIES "${MUMPS_pord_LIBRARY}") + get_filename_component(pord_lib_path ${MUMPS_pord_LIBRARY} PATH) + list(APPEND MUMPS_LIBRARY_DIRS "${pord_lib_path}") else () - if (MUMPS_FIND_REQUIRED) - message(FATAL_ERROR "Looking for mumps -- " - "libpord.a not found in ${MUMPS_DIR}/lib when required") - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for mumps -- libpord.a not found") - endif() + if (MUMPS_FIND_REQUIRED) + message(FATAL_ERROR "Looking for mumps -- " + "libpord.a not found in ${MUMPS_DIR}/lib when required") + else() + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for mumps -- libpord.a not found") endif() + endif() endif() list(REMOVE_DUPLICATES MUMPS_LIBRARY_DIRS) list(REMOVE_DUPLICATES MUMPS_INCLUDE_DIRS) @@ -499,182 +546,208 @@ list(REMOVE_DUPLICATES MUMPS_INCLUDE_DIRS) # check a function to validate the find if(MUMPS_LIBRARIES) - set(REQUIRED_LDFLAGS) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) - - # MUMPS - if (MUMPS_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${MUMPS_INCLUDE_DIRS}") - endif() - foreach(libdir ${MUMPS_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() + set(REQUIRED_LDFLAGS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # MUMPS + if (MUMPS_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${MUMPS_INCLUDE_DIRS}") + endif() + foreach(libdir ${MUMPS_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + set(REQUIRED_LIBS "${MUMPS_LIBRARIES}") + # SCALAPACK + if (MUMPS_LOOK_FOR_MPI AND SCALAPACK_FOUND) + if (SCALAPACK_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${SCALAPACK_INCLUDE_DIRS}") + endif() + foreach(libdir ${SCALAPACK_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() endforeach() - set(REQUIRED_LIBS "${MUMPS_LIBRARIES}") - # SCALAPACK - if (MUMPS_LOOK_FOR_MPI AND SCALAPACK_FOUND) - if (SCALAPACK_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${SCALAPACK_INCLUDE_DIRS}") - endif() - foreach(libdir ${SCALAPACK_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - list(APPEND REQUIRED_LIBS "${SCALAPACK_LIBRARIES}") - if (SCALAPACK_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${SCALAPACK_LINKER_FLAGS}") - endif() - endif() - # MPI - if (MUMPS_LOOK_FOR_MPI AND MPI_FOUND) - if (MPI_C_INCLUDE_PATH) - list(APPEND REQUIRED_INCDIRS "${MPI_C_INCLUDE_PATH}") - endif() - if (MPI_Fortran_LINK_FLAGS) - if (${MPI_Fortran_LINK_FLAGS} MATCHES " -") - string(REGEX REPLACE " -" "-" MPI_Fortran_LINK_FLAGS ${MPI_Fortran_LINK_FLAGS}) - endif() - list(APPEND REQUIRED_LDFLAGS "${MPI_Fortran_LINK_FLAGS}") - endif() - list(APPEND REQUIRED_LIBS "${MPI_Fortran_LIBRARIES}") - endif() - # BLAS - if (BLAS_FOUND) - if (BLAS_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${BLAS_INCLUDE_DIRS}") - endif() - foreach(libdir ${BLAS_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - list(APPEND REQUIRED_LIBS "${BLAS_LIBRARIES}") - if (BLAS_LINKER_FLAGS) - list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") - endif() - endif() - # SCOTCH - if (MUMPS_LOOK_FOR_SCOTCH AND SCOTCH_FOUND) - if (SCOTCH_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${SCOTCH_INCLUDE_DIRS}") - endif() - foreach(libdir ${SCOTCH_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - list(APPEND REQUIRED_LIBS "${SCOTCH_LIBRARIES}") - endif() - # METIS - if (MUMPS_LOOK_FOR_METIS AND METIS_FOUND) - if (METIS_INCLUDE_DIRS) - list(APPEND REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}") - endif() - foreach(libdir ${METIS_LIBRARY_DIRS}) - if (libdir) - list(APPEND REQUIRED_LIBDIRS "${libdir}") - endif() - endforeach() - list(APPEND REQUIRED_LIBS "${METIS_LIBRARIES}") - endif() - # Fortran - if (CMAKE_C_COMPILER_ID MATCHES "GNU") - find_library( - FORTRAN_gfortran_LIBRARY - NAMES gfortran - HINTS ${_lib_env} - ) - mark_as_advanced(FORTRAN_gfortran_LIBRARY) - if (FORTRAN_gfortran_LIBRARY) - list(APPEND REQUIRED_LIBS "${FORTRAN_gfortran_LIBRARY}") - endif() - elseif (CMAKE_C_COMPILER_ID MATCHES "Intel") - find_library( - FORTRAN_ifcore_LIBRARY - NAMES ifcore - HINTS ${_lib_env} - ) - mark_as_advanced(FORTRAN_ifcore_LIBRARY) - if (FORTRAN_ifcore_LIBRARY) - list(APPEND REQUIRED_LIBS "${FORTRAN_ifcore_LIBRARY}") - endif() - endif() - # EXTRA LIBS such that pthread, m, rt - list(APPEND REQUIRED_LIBS ${MUMPS_EXTRA_LIBRARIES}) - - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + list(APPEND REQUIRED_LIBS "${SCALAPACK_LIBRARIES}") + if (SCALAPACK_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${SCALAPACK_LINKER_FLAGS}") + endif() + endif() + # MPI + if (MUMPS_LOOK_FOR_MPI AND MPI_FOUND) + if (MPI_C_INCLUDE_PATH) + list(APPEND REQUIRED_INCDIRS "${MPI_C_INCLUDE_PATH}") + endif() + if (MPI_Fortran_LINK_FLAGS) + if (${MPI_Fortran_LINK_FLAGS} MATCHES " -") + string(REGEX REPLACE " -" "-" MPI_Fortran_LINK_FLAGS ${MPI_Fortran_LINK_FLAGS}) + endif() + list(APPEND REQUIRED_LDFLAGS "${MPI_Fortran_LINK_FLAGS}") + endif() + list(APPEND REQUIRED_LIBS "${MPI_Fortran_LIBRARIES}") + endif() + # BLAS + if (BLAS_FOUND) + if (BLAS_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${BLAS_INCLUDE_DIRS}") + endif() + foreach(libdir ${BLAS_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - - # test link - include(CheckFortranFunctionExists) - unset(MUMPS_PREC_S_WORKS CACHE) - check_fortran_function_exists(smumps MUMPS_PREC_S_WORKS) - mark_as_advanced(MUMPS_PREC_S_WORKS) - unset(MUMPS_PREC_D_WORKS CACHE) - check_fortran_function_exists(dmumps MUMPS_PREC_D_WORKS) - mark_as_advanced(MUMPS_PREC_D_WORKS) - unset(MUMPS_PREC_C_WORKS CACHE) - check_fortran_function_exists(cmumps MUMPS_PREC_C_WORKS) - mark_as_advanced(MUMPS_PREC_C_WORKS) - unset(MUMPS_PREC_Z_WORKS CACHE) - check_fortran_function_exists(zmumps MUMPS_PREC_Z_WORKS) - mark_as_advanced(MUMPS_PREC_Z_WORKS) - - set(MUMPS_WORKS FALSE) - if(MUMPS_PREC_S_WORKS OR MUMPS_PREC_D_WORKS OR MUMPS_PREC_C_WORKS OR MUMPS_PREC_Z_WORKS) - set(MUMPS_WORKS TRUE) - endif() - - if(MUMPS_WORKS) - # save link with dependencies - set(MUMPS_LIBRARIES_DEP "${REQUIRED_LIBS}") - set(MUMPS_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") - set(MUMPS_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") - set(MUMPS_LINKER_FLAGS "${REQUIRED_LDFLAGS}") - list(REMOVE_DUPLICATES MUMPS_LIBRARY_DIRS_DEP) - list(REMOVE_DUPLICATES MUMPS_INCLUDE_DIRS_DEP) - list(REMOVE_DUPLICATES MUMPS_LINKER_FLAGS) - else() - if(NOT MUMPS_FIND_QUIETLY) - message(STATUS "Looking for MUMPS : test of [sdcz]mumps() fails") - message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") - message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") - message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") - message(STATUS "Maybe MUMPS is linked with specific libraries. " - "Have you tried with COMPONENTS (MPI/SEQ, SCOTCH, METIS)? " - "See the explanation in FindMUMPS.cmake.") - endif() - endif() - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_FLAGS) - set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND REQUIRED_LIBS "${BLAS_LIBRARIES}") + if (BLAS_LINKER_FLAGS) + list(APPEND REQUIRED_LDFLAGS "${BLAS_LINKER_FLAGS}") + endif() + endif() + # SCOTCH + if (MUMPS_LOOK_FOR_SCOTCH AND SCOTCH_FOUND) + if (SCOTCH_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${SCOTCH_INCLUDE_DIRS}") + endif() + foreach(libdir ${SCOTCH_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + list(APPEND REQUIRED_LIBS "${SCOTCH_LIBRARIES}") + endif() + # PTSCOTCH + if (MUMPS_LOOK_FOR_PTSCOTCH AND PTSCOTCH_FOUND) + if (PTSCOTCH_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${PTSCOTCH_INCLUDE_DIRS}") + endif() + foreach(libdir ${PTSCOTCH_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + list(APPEND REQUIRED_LIBS "${PTSCOTCH_LIBRARIES}") + endif() + # METIS + if (MUMPS_LOOK_FOR_METIS AND METIS_FOUND) + if (METIS_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${METIS_INCLUDE_DIRS}") + endif() + foreach(libdir ${METIS_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + list(APPEND REQUIRED_LIBS "${METIS_LIBRARIES}") + endif() + # PARMETIS + if (MUMPS_LOOK_FOR_PARMETIS AND PARMETIS_FOUND) + if (PARMETIS_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${PARMETIS_INCLUDE_DIRS}") + endif() + foreach(libdir ${PARMETIS_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + list(APPEND REQUIRED_LIBS "${PARMETIS_LIBRARIES}") + endif() + # Fortran + if (CMAKE_C_COMPILER_ID MATCHES "GNU") + find_library( + FORTRAN_gfortran_LIBRARY + NAMES gfortran + HINTS ${_lib_env} + ) + mark_as_advanced(FORTRAN_gfortran_LIBRARY) + if (FORTRAN_gfortran_LIBRARY) + list(APPEND REQUIRED_LIBS "${FORTRAN_gfortran_LIBRARY}") + endif() + elseif (CMAKE_C_COMPILER_ID MATCHES "Intel") + find_library( + FORTRAN_ifcore_LIBRARY + NAMES ifcore + HINTS ${_lib_env} + ) + mark_as_advanced(FORTRAN_ifcore_LIBRARY) + if (FORTRAN_ifcore_LIBRARY) + list(APPEND REQUIRED_LIBS "${FORTRAN_ifcore_LIBRARY}") + endif() + endif() + # EXTRA LIBS such that pthread, m, rt + list(APPEND REQUIRED_LIBS ${MUMPS_EXTRA_LIBRARIES}) + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + include(CheckFortranFunctionExists) + unset(MUMPS_PREC_S_WORKS CACHE) + check_fortran_function_exists(smumps MUMPS_PREC_S_WORKS) + mark_as_advanced(MUMPS_PREC_S_WORKS) + unset(MUMPS_PREC_D_WORKS CACHE) + check_fortran_function_exists(dmumps MUMPS_PREC_D_WORKS) + mark_as_advanced(MUMPS_PREC_D_WORKS) + unset(MUMPS_PREC_C_WORKS CACHE) + check_fortran_function_exists(cmumps MUMPS_PREC_C_WORKS) + mark_as_advanced(MUMPS_PREC_C_WORKS) + unset(MUMPS_PREC_Z_WORKS CACHE) + check_fortran_function_exists(zmumps MUMPS_PREC_Z_WORKS) + mark_as_advanced(MUMPS_PREC_Z_WORKS) + + set(MUMPS_WORKS FALSE) + if(MUMPS_PREC_S_WORKS OR MUMPS_PREC_D_WORKS OR MUMPS_PREC_C_WORKS OR MUMPS_PREC_Z_WORKS) + set(MUMPS_WORKS TRUE) + endif() + + if(MUMPS_WORKS) + # save link with dependencies + set(MUMPS_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(MUMPS_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(MUMPS_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(MUMPS_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES MUMPS_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES MUMPS_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES MUMPS_LINKER_FLAGS) + else() + if(NOT MUMPS_FIND_QUIETLY) + message(STATUS "Looking for MUMPS : test of [sdcz]mumps() fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + message(STATUS "Maybe MUMPS is linked with specific libraries. " + "Have you tried with COMPONENTS (MPI/SEQ, SCOTCH, PTSCOTCH, METIS, PARMETIS)? " + "See the explanation in FindMUMPS.cmake.") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) endif(MUMPS_LIBRARIES) if (MUMPS_LIBRARIES) - list(GET MUMPS_LIBRARIES 0 first_lib) - get_filename_component(first_lib_path "${first_lib}" PATH) - if (${first_lib_path} MATCHES "/lib(32|64)?$") - string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") - set(MUMPS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of MUMPS library" FORCE) - else() - set(MUMPS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of MUMPS library" FORCE) - endif() + list(GET MUMPS_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(MUMPS_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of MUMPS library" FORCE) + else() + set(MUMPS_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of MUMPS library" FORCE) + endif() endif() +mark_as_advanced(MUMPS_DIR) +mark_as_advanced(MUMPS_DIR_FOUND) # check that MUMPS has been found # ------------------------------- include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MUMPS DEFAULT_MSG - MUMPS_LIBRARIES - MUMPS_WORKS) + MUMPS_LIBRARIES + MUMPS_WORKS) diff --git a/CMakeModules/morse/find/FindPAMPA.cmake b/CMakeModules/morse/find/FindPAMPA.cmake new file mode 100644 index 0000000000000000000000000000000000000000..f5f295376f61cbc9bd902a8321217890e428e6f3 --- /dev/null +++ b/CMakeModules/morse/find/FindPAMPA.cmake @@ -0,0 +1,383 @@ +### +# +# @copyright (c) 2009-2014 The University of Tennessee and The University +# of Tennessee Research Foundation. +# All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. +# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. +# +### +# +# - Find PAMPA include dirs and libraries +# Use this module by invoking find_package with the form: +# find_package(PAMPA +# [REQUIRED] # Fail with error if pampa is not found +# ) +# +# PAMPA depends on the following libraries: +# - MPI +# - PTSCOTCH +# +# This module finds headers and pampa library. +# Results are reported in variables: +# PAMPA_FOUND - True if headers and requested libraries were found +# PAMPA_INCLUDE_DIRS - pampa include directories +# PAMPA_LIBRARY_DIRS - Link directories for pampa libraries +# PAMPA_LIBRARIES - pampa component libraries to be linked +# PAMPA_INTSIZE - Number of octets occupied by a PAMPA_Num +# +# The user can give specific paths where to find the libraries adding cmake +# options at configure (ex: cmake path/to/project -DPAMPA=path/to/pampa): +# PAMPA_DIR - Where to find the base directory of pampa +# PAMPA_INCDIR - Where to find the header files +# PAMPA_LIBDIR - Where to find the library files +# The module can also look for the following environment variables if paths +# are not given as cmake variable: PAMPA_DIR, PAMPA_INCDIR, PAMPA_LIBDIR + +#============================================================================= +# Copyright 2012-2013 Inria +# Copyright 2012-2013 Emmanuel Agullo +# Copyright 2012-2013 Mathieu Faverge +# Copyright 2012 Cedric Castagnede +# Copyright 2013-2016 Florent Pruvost +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file MORSE-Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of Morse, substitute the full +# License text for the above reference.) + +if (NOT PAMPA_FOUND) + set(PAMPA_DIR "" CACHE PATH "Installation directory of PAMPA library") + if (NOT PAMPA_FIND_QUIETLY) + message(STATUS "A cache variable, namely PAMPA_DIR, has been set to specify the install directory of PAMPA") + endif() +endif() + +# PAMPA depends on MPI, try to find it +if (NOT MPI_FOUND) + if (PAMPA_FIND_REQUIRED) + find_package(MPI REQUIRED) + else() + find_package(MPI) + endif() +endif() + +# PAMPA depends on PAMPA, try to find it +if (NOT PTSCOTCH_FOUND) + if (PAMPA_FIND_REQUIRED) + find_package(PTSCOTCH REQUIRED) + else() + find_package(PTSCOTCH) + endif() +endif() + +# Looking for include +# ------------------- + +# Add system include paths to search include +# ------------------------------------------ +unset(_inc_env) +set(ENV_PAMPA_DIR "$ENV{PAMPA_DIR}") +set(ENV_PAMPA_INCDIR "$ENV{PAMPA_INCDIR}") +if(ENV_PAMPA_INCDIR) + list(APPEND _inc_env "${ENV_PAMPA_INCDIR}") +elseif(ENV_PAMPA_DIR) + list(APPEND _inc_env "${ENV_PAMPA_DIR}") + list(APPEND _inc_env "${ENV_PAMPA_DIR}/include") + list(APPEND _inc_env "${ENV_PAMPA_DIR}/include/ptscotch") +else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() +endif() +list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") +list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") +list(REMOVE_DUPLICATES _inc_env) + + +# Try to find the ptscotch header in the given paths +# ------------------------------------------------- + +set(PAMPA_hdrs_to_find "pampa.h") + +# call cmake macro to find the header path +if(PAMPA_INCDIR) + foreach(pampa_hdr ${PAMPA_hdrs_to_find}) + set(PAMPA_${pampa_hdr}_DIRS "PAMPA_${pampa_hdr}_DIRS-NOTFOUND") + find_path(PAMPA_${pampa_hdr}_DIRS + NAMES ${pampa_hdr} + HINTS ${PAMPA_INCDIR}) + mark_as_advanced(PAMPA_${pampa_hdr}_DIRS) + endforeach() +else() + if(PAMPA_DIR) + foreach(pampa_hdr ${PAMPA_hdrs_to_find}) + set(PAMPA_${pampa_hdr}_DIRS "PAMPA_${pampa_hdr}_DIRS-NOTFOUND") + find_path(PAMPA_${pampa_hdr}_DIRS + NAMES ${pampa_hdr} + HINTS ${PAMPA_DIR} + PATH_SUFFIXES "include" "include/pampa") + mark_as_advanced(PAMPA_${pampa_hdr}_DIRS) + endforeach() + else() + foreach(pampa_hdr ${PAMPA_hdrs_to_find}) + set(PAMPA_${pampa_hdr}_DIRS "PAMPA_${pampa_hdr}_DIRS-NOTFOUND") + find_path(PAMPA_${pampa_hdr}_DIRS + NAMES ${pampa_hdr} + HINTS ${_inc_env} + PATH_SUFFIXES "pampa") + mark_as_advanced(PAMPA_${pampa_hdr}_DIRS) + endforeach() + endif() +endif() + +# If found, add path to cmake variable +# ------------------------------------ +foreach(pampa_hdr ${PAMPA_hdrs_to_find}) + if (PAMPA_${pampa_hdr}_DIRS) + list(APPEND PAMPA_INCLUDE_DIRS "${PAMPA_${pampa_hdr}_DIRS}") + else () + set(PAMPA_INCLUDE_DIRS "PAMPA_INCLUDE_DIRS-NOTFOUND") + if (NOT PAMPA_FIND_QUIETLY) + message(STATUS "Looking for pampa -- ${pampa_hdr} not found") + endif() + endif() +endforeach() + +# Looking for lib +# --------------- + +# Add system library paths to search lib +# -------------------------------------- +unset(_lib_env) +set(ENV_PAMPA_LIBDIR "$ENV{PAMPA_LIBDIR}") +if(ENV_PAMPA_LIBDIR) + list(APPEND _lib_env "${ENV_PAMPA_LIBDIR}") +elseif(ENV_PAMPA_DIR) + list(APPEND _lib_env "${ENV_PAMPA_DIR}") + list(APPEND _lib_env "${ENV_PAMPA_DIR}/lib") +else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() +endif() +list(REMOVE_DUPLICATES _lib_env) + +# Try to find the ptscotch lib in the given paths +# ---------------------------------------------- + +set(PAMPA_libs_to_find "pampa;pampaerr") + +# call cmake macro to find the lib path +if(PAMPA_LIBDIR) + foreach(pampa_lib ${PAMPA_libs_to_find}) + set(PAMPA_${pampa_lib}_LIBRARY "PAMPA_${pampa_lib}_LIBRARY-NOTFOUND") + find_library(PAMPA_${pampa_lib}_LIBRARY + NAMES ${pampa_lib} + HINTS ${PAMPA_LIBDIR}) + endforeach() +else() + if(PAMPA_DIR) + foreach(pampa_lib ${PAMPA_libs_to_find}) + set(PAMPA_${pampa_lib}_LIBRARY "PAMPA_${pampa_lib}_LIBRARY-NOTFOUND") + find_library(PAMPA_${pampa_lib}_LIBRARY + NAMES ${pampa_lib} + HINTS ${PAMPA_DIR} + PATH_SUFFIXES lib lib32 lib64) + endforeach() + else() + foreach(pampa_lib ${PAMPA_libs_to_find}) + set(PAMPA_${pampa_lib}_LIBRARY "PAMPA_${pampa_lib}_LIBRARY-NOTFOUND") + find_library(PAMPA_${pampa_lib}_LIBRARY + NAMES ${pampa_lib} + HINTS ${_lib_env}) + endforeach() + endif() +endif() + +set(PAMPA_LIBRARIES "") +set(PAMPA_LIBRARY_DIRS "") +# If found, add path to cmake variable +# ------------------------------------ +foreach(pampa_lib ${PAMPA_libs_to_find}) + + if (PAMPA_${pampa_lib}_LIBRARY) + get_filename_component(${pampa_lib}_lib_path "${PAMPA_${pampa_lib}_LIBRARY}" PATH) + # set cmake variables + list(APPEND PAMPA_LIBRARIES "${PAMPA_${pampa_lib}_LIBRARY}") + list(APPEND PAMPA_LIBRARY_DIRS "${${pampa_lib}_lib_path}") + else () + list(APPEND PAMPA_LIBRARIES "${PAMPA_${pampa_lib}_LIBRARY}") + if (NOT PAMPA_FIND_QUIETLY) + message(STATUS "Looking for ptscotch -- lib ${pampa_lib} not found") + endif() + endif () + + mark_as_advanced(PAMPA_${pampa_lib}_LIBRARY) + +endforeach() +list(REMOVE_DUPLICATES PAMPA_LIBRARY_DIRS) + +# check a function to validate the find +if(PAMPA_LIBRARIES) + + set(REQUIRED_LDFLAGS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # PAMPA + if (PAMPA_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${PAMPA_INCLUDE_DIRS}") + endif() + if (PAMPA_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${PAMPA_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${PAMPA_LIBRARIES}") + add_definitions(-Drestrict=__restrict) # pampa uses the restrict keyword + list(APPEND REQUIRED_FLAGS "-Drestrict=__restrict") + # MPI + if (MPI_FOUND) + if (MPI_C_INCLUDE_PATH) + list(APPEND CMAKE_REQUIRED_INCLUDES "${MPI_C_INCLUDE_PATH}") + endif() + if (MPI_C_LINK_FLAGS) + if (${MPI_C_LINK_FLAGS} MATCHES " -") + string(REGEX REPLACE " -" "-" MPI_C_LINK_FLAGS ${MPI_C_LINK_FLAGS}) + endif() + list(APPEND REQUIRED_LDFLAGS "${MPI_C_LINK_FLAGS}") + endif() + list(APPEND REQUIRED_LIBS "${MPI_C_LIBRARIES}") + endif() + # PTSCOTCH + if (PTSCOTCH_INCLUDE_DIRS) + list(APPEND REQUIRED_INCDIRS "${PTSCOTCH_INCLUDE_DIRS}") + endif() + foreach(libdir ${PTSCOTCH_LIBRARY_DIRS}) + if (libdir) + list(APPEND REQUIRED_LIBDIRS "${libdir}") + endif() + endforeach() + list(APPEND REQUIRED_LIBS "${PTSCOTCH_LIBRARIES_DEP}") + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LDFLAGS}") + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + list(APPEND CMAKE_REQUIRED_FLAGS "${REQUIRED_FLAGS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(PAMPA_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(PAMPA_dmeshInit PAMPA_WORKS) + mark_as_advanced(PAMPA_WORKS) + + if(PAMPA_WORKS) + # save link with dependencies + set(PAMPA_LIBRARIES_DEP "${REQUIRED_LIBS}") + set(PAMPA_LIBRARY_DIRS_DEP "${REQUIRED_LIBDIRS}") + set(PAMPA_INCLUDE_DIRS_DEP "${REQUIRED_INCDIRS}") + set(PAMPA_LINKER_FLAGS "${REQUIRED_LDFLAGS}") + list(REMOVE_DUPLICATES PAMPA_LIBRARY_DIRS_DEP) + list(REMOVE_DUPLICATES PAMPA_INCLUDE_DIRS_DEP) + list(REMOVE_DUPLICATES PAMPA_LINKER_FLAGS) + else() + if(NOT PAMPA_FIND_QUIETLY) + message(STATUS "Looking for PAMPA : test of PAMPA_dmeshInit with PAMPA library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) +endif(PAMPA_LIBRARIES) + +if (PAMPA_LIBRARIES) + list(GET PAMPA_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(PAMPA_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of PAMPA library" FORCE) + else() + set(PAMPA_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of PAMPA library" FORCE) + endif() +endif() +mark_as_advanced(PAMPA_DIR) +mark_as_advanced(PAMPA_DIR_FOUND) + +# Check the size of PAMPA_Num +# --------------------------------- +set(CMAKE_REQUIRED_INCLUDES ${PAMPA_INCLUDE_DIRS}) + +include(CheckCSourceRuns) +#stdio.h and stdint.h should be included by scotch.h directly +set(PAMPA_C_TEST_PAMPA_Num_4 " +#include +#include +#include +int main(int argc, char **argv) { + if (sizeof(PAMPA_Num) == 4) + return 0; + else + return 1; +} +") + +set(PAMPA_C_TEST_PAMPA_Num_8 " +#include +#include +#include +int main(int argc, char **argv) { + if (sizeof(PAMPA_Num) == 8) + return 0; + else + return 1; +} +") +check_c_source_runs("${PAMPA_C_TEST_PAMPA_Num_4}" PAMPA_Num_4) +if(NOT PAMPA_Num_4) + check_c_source_runs("${PAMPA_C_TEST_PAMPA_Num_8}" PAMPA_Num_8) + if(NOT PAMPA_Num_8) + set(PAMPA_INTSIZE -1) + else() + set(PAMPA_INTSIZE 8) + endif() +else() + set(PAMPA_INTSIZE 4) +endif() +set(CMAKE_REQUIRED_INCLUDES "") + +# check that PAMPA has been found +# --------------------------------- +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(PAMPA DEFAULT_MSG + PAMPA_LIBRARIES + PAMPA_WORKS) diff --git a/CMakeModules/morse/find/FindPAPI.cmake b/CMakeModules/morse/find/FindPAPI.cmake new file mode 100644 index 0000000000000000000000000000000000000000..918edb43af6b4e4f259392196af4a579bfb80d11 --- /dev/null +++ b/CMakeModules/morse/find/FindPAPI.cmake @@ -0,0 +1,310 @@ +### +# +# @copyright (c) 2009-2014 The University of Tennessee and The University +# of Tennessee Research Foundation. +# All rights reserved. +# @copyright (c) 2012-2016 Inria. All rights reserved. +# @copyright (c) 2012-2014 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, Univ. Bordeaux. All rights reserved. +# +### +# +# - Find PAPI include dirs and libraries +# Use this module by invoking find_package with the form: +# find_package(PAPI +# [REQUIRED]) # Fail with error if papi is not found +# +# This module finds headers and papi library. +# Results are reported in variables: +# PAPI_FOUND - True if headers and requested libraries were found +# PAPI_INCLUDE_DIRS - papi include directories +# PAPI_LIBRARY_DIRS - Link directories for papi libraries +# PAPI_LIBRARIES - papi component libraries to be linked +# +# The user can give specific paths where to find the libraries adding cmake +# options at configure (ex: cmake path/to/project -DPAPI_DIR=path/to/papi): +# PAPI_DIR - Where to find the base directory of papi +# PAPI_INCDIR - Where to find the header files +# PAPI_LIBDIR - Where to find the library files +# The module can also look for the following environment variables if paths +# are not given as cmake variable: PAPI_DIR, PAPI_INCDIR, PAPI_LIBDIR + +#============================================================================= +# Copyright 2012-2016 Inria +# Copyright 2012-2013 Emmanuel Agullo +# Copyright 2012-2013 Mathieu Faverge +# Copyright 2012 Cedric Castagnede +# Copyright 2013-2016 Florent Pruvost +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file MORSE-Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of Morse, substitute the full +# License text for the above reference.) + +if (NOT PAPI_FOUND) + set(PAPI_DIR "" CACHE PATH "Installation directory of PAPI library") + if (NOT PAPI_FIND_QUIETLY) + message(STATUS "A cache variable, namely PAPI_DIR, has been set to specify the install directory of PAPI") + endif() +endif() + +set(ENV_PAPI_DIR "$ENV{PAPI_DIR}") +set(ENV_PAPI_INCDIR "$ENV{PAPI_INCDIR}") +set(ENV_PAPI_LIBDIR "$ENV{PAPI_LIBDIR}") +set(PAPI_GIVEN_BY_USER "FALSE") +if ( PAPI_DIR OR ( PAPI_INCDIR AND PAPI_LIBDIR) OR ENV_PAPI_DIR OR (ENV_PAPI_INCDIR AND ENV_PAPI_LIBDIR) ) + set(PAPI_GIVEN_BY_USER "TRUE") +endif() + +# Optionally use pkg-config to detect include/library dirs (if pkg-config is available) +# ------------------------------------------------------------------------------------- +include(FindPkgConfig) +find_package(PkgConfig QUIET) +if(PKG_CONFIG_EXECUTABLE AND NOT PAPI_GIVEN_BY_USER) + + pkg_search_module(PAPI papi) + if (NOT PAPI_FIND_QUIETLY) + if (PAPI_FOUND AND PAPI_LIBRARIES) + message(STATUS "Looking for PAPI - found using PkgConfig") + #if(NOT PAPI_INCLUDE_DIRS) + # message("${Magenta}PAPI_INCLUDE_DIRS is empty using PkgConfig." + # "Perhaps the path to papi headers is already present in your" + # "C(PLUS)_INCLUDE_PATH environment variable.${ColourReset}") + #endif() + else() + message(STATUS "${Magenta}Looking for PAPI - not found using PkgConfig." + "\n Perhaps you should add the directory containing papi.pc to the" + "\n PKG_CONFIG_PATH environment variable.${ColourReset}") + endif() + endif() + +endif(PKG_CONFIG_EXECUTABLE AND NOT PAPI_GIVEN_BY_USER) + +if( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT PAPI_FOUND) OR (PAPI_GIVEN_BY_USER) ) + + if (NOT PAPI_FIND_QUIETLY) + message(STATUS "Looking for PAPI - PkgConfig not used") + endif() + + # Looking for include + # ------------------- + + # Add system include paths to search include + # ------------------------------------------ + unset(_inc_env) + set(ENV_PAPI_DIR "$ENV{PAPI_DIR}") + set(ENV_PAPI_INCDIR "$ENV{PAPI_INCDIR}") + if(ENV_PAPI_INCDIR) + list(APPEND _inc_env "${ENV_PAPI_INCDIR}") + elseif(ENV_PAPI_DIR) + list(APPEND _inc_env "${ENV_PAPI_DIR}") + list(APPEND _inc_env "${ENV_PAPI_DIR}/include") + list(APPEND _inc_env "${ENV_PAPI_DIR}/include/papi") + else() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() + endif() + list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") + list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") + list(REMOVE_DUPLICATES _inc_env) + + # Try to find the papi header in the given paths + # ------------------------------------------------- + # call cmake macro to find the header path + if(PAPI_INCDIR) + set(PAPI_papi.h_DIRS "PAPI_papi.h_DIRS-NOTFOUND") + find_path(PAPI_papi.h_DIRS + NAMES papi.h + HINTS ${PAPI_INCDIR}) + else() + if(PAPI_DIR) + set(PAPI_papi.h_DIRS "PAPI_papi.h_DIRS-NOTFOUND") + find_path(PAPI_papi.h_DIRS + NAMES papi.h + HINTS ${PAPI_DIR} + PATH_SUFFIXES "include" "include/papi") + else() + set(PAPI_papi.h_DIRS "PAPI_papi.h_DIRS-NOTFOUND") + find_path(PAPI_papi.h_DIRS + NAMES papi.h + HINTS ${_inc_env} + PATH_SUFFIXES "papi") + endif() + endif() + mark_as_advanced(PAPI_papi.h_DIRS) + + # Add path to cmake variable + # ------------------------------------ + if (PAPI_papi.h_DIRS) + set(PAPI_INCLUDE_DIRS "${PAPI_papi.h_DIRS}") + else () + set(PAPI_INCLUDE_DIRS "PAPI_INCLUDE_DIRS-NOTFOUND") + if(NOT PAPI_FIND_QUIETLY) + message(STATUS "Looking for papi -- papi.h not found") + endif() + endif () + + if (PAPI_INCLUDE_DIRS) + list(REMOVE_DUPLICATES PAPI_INCLUDE_DIRS) + endif () + + + # Looking for lib + # --------------- + + # Add system library paths to search lib + # -------------------------------------- + unset(_lib_env) + set(ENV_PAPI_LIBDIR "$ENV{PAPI_LIBDIR}") + if(ENV_PAPI_LIBDIR) + list(APPEND _lib_env "${ENV_PAPI_LIBDIR}") + elseif(ENV_PAPI_DIR) + list(APPEND _lib_env "${ENV_PAPI_DIR}") + list(APPEND _lib_env "${ENV_PAPI_DIR}/lib") + else() + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") + else() + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") + endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() + endif() + list(REMOVE_DUPLICATES _lib_env) + + # Try to find the papi lib in the given paths + # ---------------------------------------------- + + # call cmake macro to find the lib path + if(PAPI_LIBDIR) + set(PAPI_papi_LIBRARY "PAPI_papi_LIBRARY-NOTFOUND") + find_library(PAPI_papi_LIBRARY + NAMES papi + HINTS ${PAPI_LIBDIR}) + else() + if(PAPI_DIR) + set(PAPI_papi_LIBRARY "PAPI_papi_LIBRARY-NOTFOUND") + find_library(PAPI_papi_LIBRARY + NAMES papi + HINTS ${PAPI_DIR} + PATH_SUFFIXES lib lib32 lib64) + else() + set(PAPI_papi_LIBRARY "PAPI_papi_LIBRARY-NOTFOUND") + find_library(PAPI_papi_LIBRARY + NAMES papi + HINTS ${_lib_env}) + endif() + endif() + mark_as_advanced(PAPI_papi_LIBRARY) + + # If found, add path to cmake variable + # ------------------------------------ + if (PAPI_papi_LIBRARY) + get_filename_component(papi_lib_path ${PAPI_papi_LIBRARY} PATH) + # set cmake variables (respects naming convention) + set(PAPI_LIBRARIES "${PAPI_papi_LIBRARY}") + set(PAPI_LIBRARY_DIRS "${papi_lib_path}") + else () + set(PAPI_LIBRARIES "PAPI_LIBRARIES-NOTFOUND") + set(PAPI_LIBRARY_DIRS "PAPI_LIBRARY_DIRS-NOTFOUND") + if(NOT PAPI_FIND_QUIETLY) + message(STATUS "Looking for papi -- lib papi not found") + endif() + endif () + + if (PAPI_LIBRARY_DIRS) + list(REMOVE_DUPLICATES PAPI_LIBRARY_DIRS) + endif () + + # check a function to validate the find + if(PAPI_LIBRARIES) + + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) + + # PAPI + if (PAPI_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${PAPI_INCLUDE_DIRS}") + endif() + if (PAPI_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${PAPI_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${PAPI_LIBRARIES}") + + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + # test link + unset(PAPI_WORKS CACHE) + include(CheckFunctionExists) + check_function_exists(PAPI_start PAPI_WORKS) + mark_as_advanced(PAPI_WORKS) + + if(NOT PAPI_WORKS) + if(NOT PAPI_FIND_QUIETLY) + message(STATUS "Looking for papi : test of PAPI_start with papi library fails") + message(STATUS "CMAKE_REQUIRED_LIBRARIES: ${CMAKE_REQUIRED_LIBRARIES}") + message(STATUS "CMAKE_REQUIRED_INCLUDES: ${CMAKE_REQUIRED_INCLUDES}") + message(STATUS "Check in CMakeFiles/CMakeError.log to figure out why it fails") + endif() + endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_LIBRARIES) + endif(PAPI_LIBRARIES) + +endif( (NOT PKG_CONFIG_EXECUTABLE) OR (PKG_CONFIG_EXECUTABLE AND NOT PAPI_FOUND) OR (PAPI_GIVEN_BY_USER) ) + +if (PAPI_LIBRARIES) + if (PAPI_LIBRARY_DIRS) + list(GET PAPI_LIBRARY_DIRS 0 first_lib_path) + else() + list(GET PAPI_LIBRARIES 0 first_lib) + get_filename_component(first_lib_path "${first_lib}" PATH) + endif() + if (${first_lib_path} MATCHES "/lib(32|64)?$") + string(REGEX REPLACE "/lib(32|64)?$" "" not_cached_dir "${first_lib_path}") + set(PAPI_DIR_FOUND "${not_cached_dir}" CACHE PATH "Installation directory of PAPI library" FORCE) + else() + set(PAPI_DIR_FOUND "${first_lib_path}" CACHE PATH "Installation directory of PAPI library" FORCE) + endif() +endif() +mark_as_advanced(PAPI_DIR) +mark_as_advanced(PAPI_DIR_FOUND) + +# check that PAPI has been found +# ------------------------------- +include(FindPackageHandleStandardArgs) +if (PKG_CONFIG_EXECUTABLE AND PAPI_FOUND) + find_package_handle_standard_args(PAPI DEFAULT_MSG + PAPI_LIBRARIES) +else() + find_package_handle_standard_args(PAPI DEFAULT_MSG + PAPI_LIBRARIES + PAPI_WORKS) +endif() diff --git a/CMakeModules/morse/find/FindPARMETIS.cmake b/CMakeModules/morse/find/FindPARMETIS.cmake index e037e5d5c0ebf6bce628594fa1c23cfec126fe02..fd2bd3f49c8b3d230868f0b228ca7b363c735872 100644 --- a/CMakeModules/morse/find/FindPARMETIS.cmake +++ b/CMakeModules/morse/find/FindPARMETIS.cmake @@ -47,10 +47,10 @@ # License text for the above reference.) if (NOT PARMETIS_FOUND) - set(PARMETIS_DIR "" CACHE PATH "Installation directory of PARMETIS library") - if (NOT PARMETIS_FIND_QUIETLY) - message(STATUS "A cache variable, namely PARMETIS_DIR, has been set to specify the install directory of PARMETIS") - endif() + set(PARMETIS_DIR "" CACHE PATH "Installation directory of PARMETIS library") + if (NOT PARMETIS_FIND_QUIETLY) + message(STATUS "A cache variable, namely PARMETIS_DIR, has been set to specify the install directory of PARMETIS") + endif() endif() @@ -63,24 +63,24 @@ unset(_inc_env) set(ENV_PARMETIS_DIR "$ENV{PARMETIS_DIR}") set(ENV_PARMETIS_INCDIR "$ENV{PARMETIS_INCDIR}") if(ENV_PARMETIS_INCDIR) - list(APPEND _inc_env "${ENV_PARMETIS_INCDIR}") + list(APPEND _inc_env "${ENV_PARMETIS_INCDIR}") elseif(ENV_PARMETIS_DIR) - list(APPEND _inc_env "${ENV_PARMETIS_DIR}") - list(APPEND _inc_env "${ENV_PARMETIS_DIR}/include") - list(APPEND _inc_env "${ENV_PARMETIS_DIR}/include/parmetis") + list(APPEND _inc_env "${ENV_PARMETIS_DIR}") + list(APPEND _inc_env "${ENV_PARMETIS_DIR}/include") + list(APPEND _inc_env "${ENV_PARMETIS_DIR}/include/parmetis") else() - if(WIN32) - string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") - else() - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{CPATH}") - list(APPEND _inc_env "${_path_env}") - string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") - list(APPEND _inc_env "${_path_env}") - endif() + if(WIN32) + string(REPLACE ":" ";" _inc_env "$ENV{INCLUDE}") + else() + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{C_INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{CPATH}") + list(APPEND _inc_env "${_path_env}") + string(REPLACE ":" ";" _path_env "$ENV{INCLUDE_PATH}") + list(APPEND _inc_env "${_path_env}") + endif() endif() list(APPEND _inc_env "${CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES}") list(APPEND _inc_env "${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}") @@ -91,23 +91,23 @@ list(REMOVE_DUPLICATES _inc_env) # ------------------------------------------------- # call cmake macro to find the header path if(PARMETIS_INCDIR) + set(PARMETIS_parmetis.h_DIRS "PARMETIS_parmetis.h_DIRS-NOTFOUND") + find_path(PARMETIS_parmetis.h_DIRS + NAMES parmetis.h + HINTS ${PARMETIS_INCDIR}) +else() + if(PARMETIS_DIR) set(PARMETIS_parmetis.h_DIRS "PARMETIS_parmetis.h_DIRS-NOTFOUND") find_path(PARMETIS_parmetis.h_DIRS NAMES parmetis.h - HINTS ${PARMETIS_INCDIR}) -else() - if(PARMETIS_DIR) - set(PARMETIS_parmetis.h_DIRS "PARMETIS_parmetis.h_DIRS-NOTFOUND") - find_path(PARMETIS_parmetis.h_DIRS - NAMES parmetis.h - HINTS ${PARMETIS_DIR} - PATH_SUFFIXES "include" "include/parmetis") - else() - set(PARMETIS_parmetis.h_DIRS "PARMETIS_parmetis.h_DIRS-NOTFOUND") - find_path(PARMETIS_parmetis.h_DIRS - NAMES parmetis.h - HINTS ${_inc_env}) - endif() + HINTS ${PARMETIS_DIR} + PATH_SUFFIXES "include" "include/parmetis") + else() + set(PARMETIS_parmetis.h_DIRS "PARMETIS_parmetis.h_DIRS-NOTFOUND") + find_path(PARMETIS_parmetis.h_DIRS + NAMES parmetis.h + HINTS ${_inc_env}) + endif() endif() mark_as_advanced(PARMETIS_parmetis.h_DIRS) @@ -115,12 +115,12 @@ mark_as_advanced(PARMETIS_parmetis.h_DIRS) # If found, add path to cmake variable # ------------------------------------ if (PARMETIS_parmetis.h_DIRS AND NOT PARMETIS_FIND_QUIETLY) - set(PARMETIS_INCLUDE_DIRS "${PARMETIS_parmetis.h_DIRS}") + set(PARMETIS_INCLUDE_DIRS "${PARMETIS_parmetis.h_DIRS}") else () - set(PARMETIS_INCLUDE_DIRS "PARMETIS_INCLUDE_DIRS-NOTFOUND") - if(NOT PARMETIS_FIND_QUIETLY) - message(STATUS "Looking for parmetis -- parmetis.h not found") - endif() + set(PARMETIS_INCLUDE_DIRS "PARMETIS_INCLUDE_DIRS-NOTFOUND") + if(NOT PARMETIS_FIND_QUIETLY) + message(STATUS "Looking for parmetis -- parmetis.h not found") + endif() endif() @@ -132,22 +132,22 @@ endif() unset(_lib_env) set(ENV_PARMETIS_LIBDIR "$ENV{PARMETIS_LIBDIR}") if(ENV_PARMETIS_LIBDIR) - list(APPEND _lib_env "${ENV_PARMETIS_LIBDIR}") + list(APPEND _lib_env "${ENV_PARMETIS_LIBDIR}") elseif(ENV_PARMETIS_DIR) - list(APPEND _lib_env "${ENV_PARMETIS_DIR}") - list(APPEND _lib_env "${ENV_PARMETIS_DIR}/lib") + list(APPEND _lib_env "${ENV_PARMETIS_DIR}") + list(APPEND _lib_env "${ENV_PARMETIS_DIR}/lib") else() - if(WIN32) - string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + if(WIN32) + string(REPLACE ":" ";" _lib_env "$ENV{LIB}") + else() + if(APPLE) + string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") else() - if(APPLE) - string(REPLACE ":" ";" _lib_env "$ENV{DYLD_LIBRARY_PATH}") - else() - string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") - endif() - list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") - list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + string(REPLACE ":" ";" _lib_env "$ENV{LD_LIBRARY_PATH}") endif() + list(APPEND _lib_env "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES}") + list(APPEND _lib_env "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") + endif() endif() list(REMOVE_DUPLICATES _lib_env) @@ -155,107 +155,110 @@ list(REMOVE_DUPLICATES _lib_env) # ---------------------------------------------- # call cmake macro to find the lib path if(PARMETIS_LIBDIR) + set(PARMETIS_parmetis_LIBRARY "PARMETIS_parmetis_LIBRARY-NOTFOUND") + find_library(PARMETIS_parmetis_LIBRARY + NAMES parmetis + HINTS ${PARMETIS_LIBDIR}) +else() + if(PARMETIS_DIR) set(PARMETIS_parmetis_LIBRARY "PARMETIS_parmetis_LIBRARY-NOTFOUND") find_library(PARMETIS_parmetis_LIBRARY - NAMES parmetis - HINTS ${PARMETIS_LIBDIR}) -else() - if(PARMETIS_DIR) - set(PARMETIS_parmetis_LIBRARY "PARMETIS_parmetis_LIBRARY-NOTFOUND") - find_library(PARMETIS_parmetis_LIBRARY - NAMES parmetis - HINTS ${PARMETIS_DIR} - PATH_SUFFIXES lib lib32 lib64) - else() - set(PARMETIS_parmetis_LIBRARY "PARMETIS_parmetis_LIBRARY-NOTFOUND") - find_library(PARMETIS_parmetis_LIBRARY - NAMES parmetis - HINTS ${_lib_env}) - endif() + NAMES parmetis + HINTS ${PARMETIS_DIR} + PATH_SUFFIXES lib lib32 lib64) + else() + set(PARMETIS_parmetis_LIBRARY "PARMETIS_parmetis_LIBRARY-NOTFOUND") + find_library(PARMETIS_parmetis_LIBRARY + NAMES parmetis + HINTS ${_lib_env}) + endif() endif() mark_as_advanced(PARMETIS_parmetis_LIBRARY) # If found, add path to cmake variable # ------------------------------------ if (PARMETIS_parmetis_LIBRARY) - get_filename_component(parmetis_lib_path "${PARMETIS_parmetis_LIBRARY}" PATH) - # set cmake variables - set(PARMETIS_LIBRARIES "${PARMETIS_parmetis_LIBRARY}") - set(PARMETIS_LIBRARY_DIRS "${parmetis_lib_path}") + get_filename_component(parmetis_lib_path "${PARMETIS_parmetis_LIBRARY}" PATH) + # set cmake variables + set(PARMETIS_LIBRARIES "${PARMETIS_parmetis_LIBRARY}") + set(PARMETIS_LIBRARY_DIRS "${parmetis_lib_path}") else () - set(PARMETIS_LIBRARIES "PARMETIS_LIBRARIES-NOTFOUND") - set(PARMETIS_LIBRARY_DIRS "PARMETIS_LIBRARY_DIRS-NOTFOUND") - if (NOT PARMETIS_FIND_QUIETLY) - message(STATUS "Looking for parmetis -- lib parmetis not found") - endif() + set(PARMETIS_LIBRARIES "PARMETIS_LIBRARIES-NOTFOUND") + set(PARMETIS_LIBRARY_DIRS "PARMETIS_LIBRARY_DIRS-NOTFOUND") + if (NOT PARMETIS_FIND_QUIETLY) + message(STATUS "Looking for parmetis -- lib parmetis not found") + endif() endif () # check a function to validate the find if(PARMETIS_LIBRARIES) - set(REQUIRED_INCDIRS) - set(REQUIRED_LIBDIRS) - set(REQUIRED_LIBS) + set(REQUIRED_INCDIRS) + set(REQUIRED_LIBDIRS) + set(REQUIRED_LIBS) - # PARMETIS - if (PARMETIS_INCLUDE_DIRS) - set(REQUIRED_INCDIRS "${PARMETIS_INCLUDE_DIRS}") - endif() - if (PARMETIS_LIBRARY_DIRS) - set(REQUIRED_LIBDIRS "${PARMETIS_LIBRARY_DIRS}") - endif() - set(REQUIRED_LIBS "${PARMETIS_LIBRARIES}") - # m - find_library(M_LIBRARY NAMES m) - if(M_LIBRARY) - list(APPEND REQUIRED_LIBS "-lm") - endif() + # PARMETIS + if (PARMETIS_INCLUDE_DIRS) + set(REQUIRED_INCDIRS "${PARMETIS_INCLUDE_DIRS}") + endif() + if (PARMETIS_LIBRARY_DIRS) + set(REQUIRED_LIBDIRS "${PARMETIS_LIBRARY_DIRS}") + endif() + set(REQUIRED_LIBS "${PARMETIS_LIBRARIES}") + # m + find_library(M_LIBRARY NAMES m) + mark_as_advanced(M_LIBRARY) + if(M_LIBRARY) + list(APPEND REQUIRED_LIBS "-lm") + endif() - # set required libraries for link - set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") - set(CMAKE_REQUIRED_LIBRARIES) - foreach(lib_dir ${REQUIRED_LIBDIRS}) - list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") - endforeach() - list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") - string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + # set required libraries for link + set(CMAKE_REQUIRED_INCLUDES "${REQUIRED_INCDIRS}") + set(CMAKE_REQUIRED_LIBRARIES) + foreach(lib_dir ${REQUIRED_LIBDIRS}) + list(APPEND CMAKE_REQUIRED_LIBRARIES "-L${lib_dir}") + endforeach() + list(APPEND CMAKE_REQUIRED_LIBRARIES "${REQUIRED_LIBS}") + string(REGEX REPLACE "^ -" "-" CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - # test link - unset(PARMETIS_WORKS CACHE) - include(CheckFunctionExists) - check_function_exists(ParMETIS_V3_NodeND PARMETIS_WORKS) - mark_as_advanced(PARMETIS_WORKS) + # test link + unset