如何使用CMake混合编译HIP和Fortran

k4emjkb1  于 2023-02-12  发布在  其他
关注(0)|答案(1)|浏览(165)

我不知道如何使用CMake混合HIP编译和Fortran。下面是一个演示。
我有3个文件:

  • fcode.f90
SUBROUTINE fcode()
      implicit double precision (a-h, o-z)
      parameter (M=64)
      dimension x(M),y(M),z(M)
      do k=1, M
           x(k) = 1.0
           y(k) = 2.0
           z(k) = 0.0
      end do  
      call hipcode(x,y,z,M)
      do k = 1, M
         if ( z(k) .ne. 3.0 ) then
           write(6,*) 'u fail !'
           return
         endif
      end do
      write(6,*)' PASSED !'
      return
end
  • hipcode.cpp
#include <hip/hip_runtime.h>

#define HIP_ASSERT(status) assert(status == hipSuccess)

__global__ void add(double *x, double *y, double *z, const unsigned int M) {
  z[threadIdx.x] = x[threadIdx.x] + y[threadIdx.x];
}

extern "C" void hipcode_(double *h_x, double *h_y, double *h_z, int &M) {

  HIP_ASSERT(hipSetDevice(0));

  double *d_x, *d_y, *d_z;
  HIP_ASSERT(hipMalloc((void **)&d_x, M * sizeof(double)));
  HIP_ASSERT(hipMalloc((void **)&d_y, M * sizeof(double)));
  HIP_ASSERT(hipMalloc((void **)&d_z, M * sizeof(double)));

  HIP_ASSERT(hipMemcpy(d_x, h_x, M * sizeof(double), hipMemcpyHostToDevice));
  HIP_ASSERT(hipMemcpy(d_y, h_y, M * sizeof(double), hipMemcpyHostToDevice));
  HIP_ASSERT(hipMemcpy(d_z, h_z, M * sizeof(double), hipMemcpyHostToDevice));

  hipLaunchKernelGGL(add, 1, 64, 0, 0, d_x, d_y, d_z, M);
  HIP_ASSERT(hipMemcpy(h_z, d_z, M * sizeof(double), hipMemcpyDeviceToHost));

  hipFree(d_x);
  hipFree(d_y);
  hipFree(d_z);
}
  • main.f90
call fcode()
    stop
end

我写了一个Makefile来编译它,它可以工作,但是我不知道怎么用cmake来编译它。

OBJS=main.o fcode.o hipcode.o
FC=gfortran
HIPCC=hipcc
FCFLAGS=-c
HIPCCFLAGS=-c
LDFLAGS=-lgfortran
all :
        $(HIPCC) $(HIPCCFLAGS) hipcode.cpp
        $(FC) $(FCFLAGS) fcode.f90
        $(FC) $(FCFLAGS) main.f90
        $(HIPCC) $(OBJS) $(LDFLAGS) -o test

这是我的CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(test LANGUAGES Fortran CXX)

# source file: hipcode.cpp fcode.f90 main.f90
# target:
# hipcc -c hipcode.cpp
# gfortran -c fcode.f90
# gfortran -c main.f90
# hipcc hipcode.o fcode.o main.o -lgfortran -o test

set(sources_list hipcode.cpp)
set(raw_sources_list_f90 fcode.f90)

# find hip
find_package(HIP QUIET)

set(CMAKE_HIP_FLAGS "${CMAKE_CXX_FLAGS} -D__HIP_PLATFORM_HCC__  --offload-arch=gfx906")
set(HIP_CLANG_FLAGS "${HIP_CLANG_FLAG} --hip-link")

set_source_files_properties(${sources_list} PROPERTIES HIP_SOURCE_PROPERTY_FORMAT 1)
set(MY_SOURCE_FILES ${sources_list})
set(MY_TARGET_NAME hipcode)
set(MY_HIPCC_OPTIONS "--hip-link")
set(HIP_TARGET_LINK_LIB "rocm/hip/lib/libamdhip64.so" )
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -x hip -fgpu-rdc --hip-link  -std=c++14 -g")
set(CMAKE_CXX_COMPILER "hipcc")
set(CMAKE_HIP_FLAFS "${CMAKE_HIP_FLAGS} --hip-link")
set(CMAKE_HIP_LINKER_WRAPPER_FLAG "--hip-link")
set(CMAKE_CXX_LINK_FLAGS    "  -fgpu-rdc --hip-link  -std=c++14 ")
set(HIP_HIPCC_CMAKE_LINKER_HELPER "hipcc")
set(HIP_CLANG_PATH   " ")
set(HIP_CLANG_PARALLEL_BUILD_LINK_OPTIONS " ")
add_library(${MY_TARGET_NAME} ${MY_SOURCE_FILES})
target_link_libraries(${MY_TARGET_NAME}  ${HIP_TARGET_LINK_LIB} )

add_library(fcodef90 STATIC ${raw_sources_list_f90})
target_link_libraries(fcodef90 hipcode)

我使用CXX=hipcc cmake .. && make -j构建演示,它通过了。

但是我得到了一个错误:“未定义对'hipcode_'的引用”,那么如何修改CMakeLists.txt?

b4lqfgs4

b4lqfgs41#

首先再次感谢大家,在使用了nm之后,我意识到也许我需要添加单独的编译选项,then I found answer here,好了,非常感谢!
最后编译的命令是

gfortran -c main.f90
hipcc -fgpu-rdc --hip-link main.o libfcode.a libhipcode.a -lgfortran

相关问题