Dear Alberto,
Using CMake modules is generally the best approach to take, because it
means that you do not hard-code the library locations into your program
setup, and it thus remains portable for both code distribution and when you
update any libraries that you use. Furthermore, if this external library
itself has other dependencies, then it ensures that all of those
dependencies are also correctly linked against. So its the most fool-proof
approach to making sure that you don't run into build issues now nor
further down the line.
I see that CMake ships with a module to find Lapack, but using it sensibly
is not actually as straight forward as it could be :-/ So I've setup an
example based on step-1 (attached) that calls some Lapack functions. These
functions are marked as "external" since I don't appear have the lapacke.h
header on my machine. If you look at CMakeLists.txt for this example,
below the DEAL_II_INVOKE_AUTOPILOT() line are all of the commands necessary
to link to a generic Lapack installation. Unfortunately the standard
FindLAPACK module that CMake provides does not accept hints for the path to
Lapack, so I borrowed a work-around
<https://github.com/dealii/dealii/blob/master/cmake/modules/FindLAPACK.cmake#L34>
for this from our own module.
To configure this example, you would first run
cmake -DDEAL_II_DIR=/path/to/deal.II .
which would then autodetect any lapack installation in path. If you need to
specify the location of the lapack installation, you could run
cmake -DLAPACK_DIR=/path/to/lapack -DDEAL_II_DIR=/path/to/deal.II .
instead.
Please let me know if this resolves the problem for you.
Best,
Jean-Paul
> Hi, I was too rushy. It is not working yet.
> Let me see if I understand. I do know where my mkl libraries are, but if I
> edit the cmakelist.txt file with
> target_link_libraries(code_exe ${lapackblas_libraries}
> I have an error message. So, basically, I do not know how to instruct
> Cmake how to link lapack libraries. Would findlapack.cmake sort it out? If
> so, can you suggest how to edit the step-18 cmakelist? I really appreciate
> your help with this issue.
> Alberto
On Tuesday, March 28, 2017 at 1:49:08 AM UTC+2, Alberto Salvadori wrote:
>
> Thank you, Jean-Paul, it was very useful. It works well.
> Alberto
>
>
> *Alberto Salvadori* Dipartimento di Ingegneria Civile, Architettura,
> Territorio, Ambiente e di Matematica (DICATAM)
> Universita` di Brescia, via Branze 43, 25123 Brescia
> Italy
> tel 030 3711239
> fax 030 3711312
>
> e-mail:
> [email protected]
> web-pages:
> http://m4lab.unibs.it/faculty.html
> http://dicata.ing.unibs.it/salvadori
>
> On Mon, Mar 27, 2017 at 10:48 AM, Jean-Paul Pelteret <> wrote:
>
>> Hi Alberto,
>>
>> So, if I understand correctly, you've made modifications to the
>> CMakeLists.txt that governs your modified example problem as opposed to
>> linking deal.II itself directly to Lapack. I would say that the most simple
>> (although time-consuming) way to get the correct linker line would be to
>> build deal.II with Lapack enabled. You can do this my adding the following
>> lines to the configuration line for deal.II:
>> cmake -DDEAL_II_WITH_LAPACK:BOOL=ON -DLAPACK_DIR=/path/to/lapack etc...
>> Then every time that you link against the deal.II library, it will
>> automatically link against LAPACK.
>>
>> Otherwise if you're really prefer to keep it local to your project then
>> you'd best do it by adding a cmake module such as this one
>> <https://github.com/Kitware/CMake/blob/master/Modules/FindLAPACK.cmake>.
>> These will help you include all of the header files into your project that
>> you need to, as well as correctly link the LAPACK library (and any of its
>> dependencies) itself.
>>
>> I hope that this helps you.
>>
>> Best regards,
>> Jean-Paul
>>
>>
>> On Monday, March 27, 2017 at 4:07:17 PM UTC+2, Alberto Salvadori wrote:
>>>
>>> Hi,
>>>
>>>
>>> I appreciate any help on the issue below.
>>>
>>>
>>> Moving from step-17 and step-18, I have been developing a non linear
>>> solver for mechanical problems. It is a way to learn about deal.II rather
>>> than else. Conceptually it is rather simple, I have implemented some
>>> material model drivers (as J2 plasticity, for instance ) and a
>>> Newton-Raphson scheme.
>>>
>>>
>>> In my material model however, I am using lapack (specifically lapacke or
>>> mkl). It turned out that I am not sufficiently skilled to modify the cmake
>>> file in order to link deal.II with those libraries. I wonder if anyone can
>>> provide some help.
>>>
>>> The error reads as follows:
>>>
>>>
>>> [ 22%] *Linking CXX executable step-18*
>>>
>>> Undefined symbols for architecture x86_64:
>>>
>>> "_LAPACKE_dgesv", referenced from:
>>>
>>> ttl::lib::solve_impl<ttl::expressions::Bind<ttl::Tensor<4, 2,
>>> double> const&, std::__1::tuple<ttl::Index<(char)4>, ttl::Index<(char)3>,
>>> ttl::Index<(char)2>, ttl::Index<(char)1> > >,
>>> ttl::expressions::Bind<ttl::Tensor<2, 2, double> const&,
>>> std::__1::tuple<ttl::Index<(char)2>, ttl::Index<(char)1> > >,
>>> 4>::op(ttl::expressions::Bind<ttl::Tensor<4, 2, double> const&,
>>> std::__1::tuple<ttl::Index<(char)4>, ttl::Index<(char)3>,
>>> ttl::Index<(char)2>, ttl::Index<(char)1> > >,
>>> ttl::expressions::Bind<ttl::Tensor<2, 2, double> const&,
>>> std::__1::tuple<ttl::Index<(char)2>, ttl::Index<(char)1> > >) in
>>> step-18.cc.o
>>>
>>> "_LAPACKE_dgetrf", referenced from:
>>>
>>> int ttl::lib::inverse_impl<ttl::expressions::Bind<ttl::Tensor<4,
>>> 2, double> const&, std::__1::tuple<ttl::Index<(char)4>,
>>> ttl::Index<(char)3>, ttl::Index<(char)2>, ttl::Index<(char)1> > >,
>>> 4>::op<ttl::Tensor<4, 2, double> >(ttl::expressions::Bind<ttl::Tensor<4, 2,
>>> double> const&, std::__1::tuple<ttl::Index<(char)4>, ttl::Index<(char)3>,
>>> ttl::Index<(char)2>, ttl::Index<(char)1> > >, ttl::Tensor<4, 2, double>&)
>>> in step-18.cc.o
>>>
>>> "_LAPACKE_dgetri", referenced from:
>>>
>>> int ttl::lib::inverse_impl<ttl::expressions::Bind<ttl::Tensor<4,
>>> 2, double> const&, std::__1::tuple<ttl::Index<(char)4>,
>>> ttl::Index<(char)3>, ttl::Index<(char)2>, ttl::Index<(char)1> > >,
>>> 4>::op<ttl::Tensor<4, 2, double> >(ttl::expressions::Bind<ttl::Tensor<4, 2,
>>> double> const&, std::__1::tuple<ttl::Index<(char)4>, ttl::Index<(char)3>,
>>> ttl::Index<(char)2>, ttl::Index<(char)1> > >, ttl::Tensor<4, 2, double>&)
>>> in step-18.cc.o
>>>
>>> ld: symbol(s) not found for architecture x86_64
>>>
>>> clang: *error: *linker command failed with exit code 1 (use -v to see
>>> invocation)
>>>
>>> make[6]: *** [step-18] Error 1
>>>
>>> make[5]: *** [CMakeFiles/step-18.dir/all] Error 2
>>>
>>> make[4]: *** [all] Error 2
>>>
>>> make[3]: *** [CMakeFiles/release] Error 2
>>>
>>> make[2]: *** [CMakeFiles/release.dir/all] Error 2
>>>
>>> make[1]: *** [CMakeFiles/release.dir/rule] Error 2
>>>
>>> make: *** [release] Error 2
>>>
>>> after slight modifications of the cmakelist.txt file (adding the new
>>> source files, basically).
>>>
>>>
>>> By the way, I was able to link libraries to deal.II within Xcode and it
>>> worked out well.
>>>
>>>
>>> Thanks
>>>
>>> Alberto
>>>
>> --
>> The deal.II project is located at http://www.dealii.org/
>> For mailing list/forum options, see
>> https://groups.google.com/d/forum/dealii?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "deal.II User Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> Informativa sulla Privacy: http://www.unibs.it/node/8155
>
--
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see
https://groups.google.com/d/forum/dealii?hl=en
---
You received this message because you are subscribed to the Google Groups
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
##
# CMake script for the step-1 tutorial program:
##
# Set the name of the project and target:
SET(TARGET "step-1")
# Declare all source files the target consists of. Here, this is only
# the one step-X.cc file, but as you expand your project you may wish
# to add other source files as well. If your project becomes much larger,
# you may want to either replace the following statement by something like
# FILE(GLOB_RECURSE TARGET_SRC "source/*.cc")
# FILE(GLOB_RECURSE TARGET_INC "include/*.h")
# SET(TARGET_SRC ${TARGET_SRC} ${TARGET_INC})
# or switch altogether to the large project CMakeLists.txt file discussed
# in the "CMake in user projects" page accessible from the "User info"
# page of the documentation.
SET(TARGET_SRC
${TARGET}.cc
)
# Usually, you will not need to modify anything beyond this point...
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
# Append module path
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
# Find an installed version of deal.II
FIND_PACKAGE(deal.II 8.4 QUIET
HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR}
)
IF(NOT ${deal.II_FOUND})
MESSAGE(FATAL_ERROR "\n"
"*** Could not locate a (sufficiently recent) version of deal.II. ***\n\n"
"You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to
cmake\n"
"or set an environment variable \"DEAL_II_DIR\" that contains this path."
)
ENDIF()
# Have deal.II setup the target executable
DEAL_II_INITIALIZE_CACHED_VARIABLES()
PROJECT(${TARGET})
DEAL_II_INVOKE_AUTOPILOT()
# Apparently to be able to pass a hint to CMake as to where
# Lapack resides requires some tricks.
# These lines were borrowed from deal.II's CMake module
SET(LAPACK_DIR "" CACHE PATH "An optional hint to a LAPACK installation")
SET_IF_EMPTY(LAPACK_DIR "$ENV{LAPACK_DIR}")
SET(_cmake_prefix_path_backup "${CMAKE_PREFIX_PATH}")
SET(CMAKE_PREFIX_PATH ${LAPACK_DIR} ${_cmake_prefix_path_backup})
# Find an installed version of Lapack using CMake's
# built-in module
# This has to come after the call to autopilot so that
# CMake knows that there is a valid C++ compiler that
# can be used with Lapack.
# If put before, one see's the error
# "FindLAPACK requires Fortran, C, or C++ to be enabled."
FIND_PACKAGE(LAPACK REQUIRED)
# Revert the CMake trickery
SET(CMAKE_PREFIX_PATH ${_cmake_prefix_path_backup})
# Setup project with Lapack
IF(LAPACK_FOUND)
MESSAGE("-- Found LAPACK!")
MESSAGE("-- Include dir: " ${LAPACK_INCLUDE_DIR})
MESSAGE("-- Libraries: " ${LAPACK_LIBRARIES})
SET (HAVE_LAPACK " ")
# Add external package to linker line
INCLUDE_DIRECTORIES (${LAPACK_INCLUDE_DIR})
TARGET_LINK_LIBRARIES (${TARGET} ${LAPACK_LIBRARIES})
ELSE()
MESSAGE(FATAL_ERROR "\n"
"*** Could not locate LAPACK. ***\n\n"
)
SET (HAVE_LAPACK "//")
ENDIF()
/* ---------------------------------------------------------------------
*
* Copyright (C) 1999 - 2015 by the deal.II authors
*
* This file is part of the deal.II library.
*
* The deal.II library is free software; you can use it, redistribute
* it, and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* The full text of the license can be found in the file LICENSE at
* the top level of the deal.II distribution.
*
* ---------------------------------------------------------------------
*/
#include <deal.II/grid/tria.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/manifold_lib.h>
#include <deal.II/grid/grid_out.h>
// #include <lapacke.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <cmath>
using namespace dealii;
void dealii_function ()
{
Triangulation<2> triangulation;
GridGenerator::hyper_cube (triangulation);
triangulation.refine_global (4);
std::ofstream out ("grid-1.eps");
GridOut grid_out;
grid_out.write_eps (triangulation, out);
std::cout << "Grid written to grid-1.eps" << std::endl;
}
// Taken from
// https://stackoverflow.com/questions/10112135/understanding-lapack-calls-in-c-with-a-simple-example
extern "C" void dgetrf_(int* dim1, int* dim2, double* a, int* lda, int* ipiv, int* info);
extern "C" void dgetrs_(char *TRANS, int *N, int *NRHS, double *A, int *LDA, int *IPIV, double *B, int *LDB, int *INFO );
void lapack_function ()
{
char trans = 'N';
int dim = 2;
int nrhs = 1;
int LDA = dim;
int LDB = dim;
int info;
std::vector<double> a, b;
a.push_back(1);
a.push_back(1);
a.push_back(1);
a.push_back(-1);
b.push_back(2);
b.push_back(0);
int ipiv[3];
dgetrf_(&dim, &dim, &*a.begin(), &LDA, ipiv, &info);
dgetrs_(&trans, &dim, &nrhs, & *a.begin(), &LDA, ipiv, & *b.begin(), &LDB, &info);
std::cout << "solution is:";
std::cout << "[" << b[0] << ", " << b[1] << ", " << "]" << std::endl;
std::cout << "Info = " << info << std::endl;
}
int main ()
{
dealii_function ();
lapack_function ();
}