Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MultiField on GPU #201

Open
wants to merge 71 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
a12114f
Add RegisterPointerInfo
wdeconinck Apr 26, 2024
22d7fb7
1) sync_host_device to skip unused fields; 2) xx-needs-update means …
sbrdar Apr 22, 2024
b7c37d1
add FielSet cummulative gpu operations: allocate_device, update_devic…
sbrdar Apr 22, 2024
3b582bc
Fix atlas_fctest_field_gpu_device with gt storage
wdeconinck Apr 25, 2024
e59fe9c
Use standard CMake find_package(OpenACC) instead of handcrafted flags
wdeconinck Apr 25, 2024
d74086e
Trace GPU events when ATLAS_TRACE_MEMORY=1
wdeconinck Apr 26, 2024
e41689b
1) Pass a config argument from Field down to Array (defaulted to util…
sbrdar Apr 27, 2024
590d37d
Disable atlas_test_field_pinning, as test_field_pinning.cc not found
wdeconinck Apr 29, 2024
c2162f7
Add copy of Config for Fortran
sbrdar Apr 29, 2024
2f8f0d9
forgot to add unit test for pinning memory of Field
sbrdar Apr 29, 2024
3003ce6
add -options- argument in functionspace%create_field; adapt unit test…
sbrdar Apr 29, 2024
d6ac142
also add options in create_field called from atlas_functionspace_Bloc…
sbrdar Apr 29, 2024
0548225
trace report for Field with memory pinning; 2) remove pinnen memory r…
sbrdar Apr 29, 2024
8fcecba
enforced pinning via eckit::Resource (by Willem)
sbrdar Apr 29, 2024
5f4b5f9
make the options argument pass down to ArrayDataStore
sbrdar Apr 29, 2024
946fef6
move host_memory booleans to ArrayDataStore
sbrdar Apr 29, 2024
1576efc
Tidy, revert host_memory_pinning to NativeDataStore
wdeconinck Apr 30, 2024
9f64a4f
Fix test
wdeconinck Apr 30, 2024
5c74b9c
add thorough tests on memory pinning and mapping of Field
sbrdar May 8, 2024
a6ba9c3
a working c++ usage of field->device_data in ACC-deviceptr (not nice …
sbrdar May 8, 2024
76fa5ff
1) add field%device_data and Fortran API backend; 2) improve the unit…
sbrdar May 8, 2024
49ab5b8
fix the unit test - remove external_acc_routine with device pointer a…
sbrdar May 13, 2024
cc2ad95
bug fix in calling for device_data from Field_module.fypp (thx Willem)
sbrdar May 15, 2024
ff2cb5f
improve the Fortran unit test for wrapping of discontiguous data
sbrdar May 15, 2024
20220b0
strides on the device do not correspond to the device shape in case o…
sbrdar May 15, 2024
f19e676
using cudaMemcpy2D to do strided copy of discontiguous data
sbrdar May 15, 2024
4d8ed39
add c-test for wrapping discontiguous data (with Willem)
sbrdar May 15, 2024
cb13d32
update unit test for wrapping of the discontiguous data; fix test_field
sbrdar May 17, 2024
744e68f
bug fix in wrapping of discontiguous data; make unit test on wrapping…
sbrdar May 17, 2024
8d38b9d
bug fix in wrapping discontiguous data to make Fortran and C++ unit t…
sbrdar May 17, 2024
c6142b7
add all possible tests for slicing of a 4d array for the wrapping of …
sbrdar May 17, 2024
cf72be7
Introducing MultiField
wdeconinck Mar 25, 2022
5929613
Support for vector fields in multifield
wdeconinck Mar 28, 2022
0a9e45a
Use util::Factory for MultiFieldCreatorFactory
wdeconinck Apr 4, 2022
5762a54
MultiField with ArrayAllocator
wdeconinck Apr 5, 2022
1884eda
provide nproma in addition to block_size, since the first block_size …
sbrdar Aug 23, 2023
be750f9
add Fortran interface and a unit test for multifield
sbrdar Aug 31, 2023
c745473
Add FieldObserver::onFieldDestruction
wdeconinck Sep 5, 2023
102c01d
Use MultiFieldArrayRegistry to avoid accidental deletion of multifiel…
wdeconinck Sep 5, 2023
721672a
fix namespace
sbrdar Sep 5, 2023
ff04675
extend the Fortran interface of MultiField to return its FieldSet; ex…
sbrdar Sep 6, 2023
86a961c
a unit test for FieldSet concatenation
sbrdar Sep 7, 2023
f27eb06
extend the unit tests for FieldSet
sbrdar Sep 7, 2023
8c233c9
1) turn fypp to F90; 2) add a Fortran unit test for MultiField
sbrdar Sep 7, 2023
b6087cf
remove file
sbrdar Sep 7, 2023
798c4bd
improve Fortran unit test for MultiField
sbrdar Sep 7, 2023
1e15af0
add data access by array and index for MultiField plus a unit test fo…
sbrdar Sep 12, 2023
0ab9946
make compile again
sbrdar Sep 21, 2023
c35c13b
add device_data on FieldSet in Fortran API
sbrdar May 21, 2024
5f16f02
bug fix, do not attempt the acc_map when da^C discontiguous
sbrdar May 21, 2024
96e2918
pass config through MultiField down to Array (with Willem)
sbrdar May 22, 2024
baa4cd3
Merge branch 'feature/gpu_discontiguous_data' of github.com:ecmwf/atl…
sbrdar May 22, 2024
9570229
WrappedArray has to know if the device memory is mapped to the host m…
sbrdar May 23, 2024
8db9b44
make compile on GH200 (by Willem)
sbrdar May 23, 2024
33083ef
make pinning work correctly; add tracing to Array cuda calls (with Wi…
sbrdar May 23, 2024
179e07d
restructure MultiField construction (with Willem)
sbrdar Sep 4, 2024
f55c748
fix MultiField constructor for C based only on datatype, shape, var_n…
sbrdar Sep 9, 2024
5d30f10
add MultiFieldCreatorArray - a generic MultiField constructor from da…
sbrdar Sep 11, 2024
715125a
MultiFieldCreatorIFS does not need this constructor
sbrdar Sep 16, 2024
3d9b6e9
Config-constructor for MultiFieldCreatorArray
sbrdar Sep 16, 2024
6fe2801
add problematic multifield-array test with config
sbrdar Sep 16, 2024
e9546be
Merge branch 'develop' into feature/gpu_discontiguous_data
sbrdar Sep 16, 2024
f216567
Merge branch 'develop' into feature/gpu_discontiguous_data
sbrdar Sep 16, 2024
4f2092c
remove config argument in many Field and Array constructors
sbrdar Sep 16, 2024
b84a58a
bug fix in the IFS field creator
sbrdar Sep 16, 2024
7f33861
bypass Intel compiler problem
sbrdar Sep 17, 2024
3153f92
bug fix in MultiFieldCreatorArray
sbrdar Sep 17, 2024
b666b4d
fix MultiField Fortran API constructor to fall back to C-implementation
sbrdar Sep 18, 2024
5f16559
remove debug output
sbrdar Sep 18, 2024
946ed54
remove debug output
sbrdar Sep 18, 2024
e84dc2e
Merge branch 'develop' into feature/gpu_discontiguous_data
sbrdar Sep 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ find_package( ecbuild 3.4 REQUIRED HINTS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CUR

project( atlas LANGUAGES CXX )

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set( ATLAS_BITS_GLOBAL 64 CACHE STRING "bits used to define a global index (atlas::gidx_t)" )
set( ATLAS_BITS_LOCAL 32 CACHE STRING "bits used to define a local index (atlas::idx_t)" )

Expand Down
2 changes: 1 addition & 1 deletion atlas_io/src/atlas_io/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@ ecbuild_add_library( TARGET atlas_io
${CMAKE_CURRENT_BINARY_DIR}/detail/defines.h
)

target_compile_features( atlas_io PUBLIC cxx_std_17 )
#target_compile_features( atlas_io PUBLIC cxx_std_17 )
10 changes: 9 additions & 1 deletion cmake/features/ACC.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ if( atlas_HAVE_ACC )
set( ACC_Fortran_FLAGS ${OpenACC_Fortran_FLAGS} )
set( ACC_C_FLAGS ${OpenACC_C_FLAGS} )
endif()
endif()

if (ATLAS_FIND_OPENACC)
enable_language(C) # So that find_package(OpenACC) looks C components
find_package(OpenACC)
endif()

ecbuild_add_option( FEATURE ACC
DESCRIPTION "OpenACC capable data structures"
CONDITION HAVE_CUDA AND OpenACC_C_FOUND )

else()
set( HAVE_ACC 0 )
Expand Down
6 changes: 3 additions & 3 deletions cmake/project_summary.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ endif()
if( atlas_HAVE_ACC )

ecbuild_info( "ACC" )
ecbuild_info( " ACC_C_COMPILER : [${ACC_C_COMPILER}]" )
ecbuild_info( " ACC_C_FLAGS : [${ACC_C_FLAGS}]" )
ecbuild_info( " ACC_Fortran_FLAGS : [${ACC_Fortran_FLAGS}]" )
ecbuild_info( " OpenACC_C_FLAGS : [${OpenACC_C_FLAGS}]" )
ecbuild_info( " OpenACC_CXX_FLAGS : [${OpenACC_CXX_FLAGS}]" )
ecbuild_info( " OpenACC_Fortran_FLAGS : [${OpenACC_Fortran_FLAGS}]" )

endif()

Expand Down
14 changes: 14 additions & 0 deletions src/atlas/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,24 @@ field/FieldSet.cc
field/FieldSet.h
field/MissingValue.cc
field/MissingValue.h
field/MultiField.cc
field/MultiField.h
field/MultiFieldCreator.cc
field/MultiFieldCreator.h
field/MultiFieldCreatorIFS.cc
field/MultiFieldCreatorIFS.h
field/MultiFieldCreatorArray.cc
field/MultiFieldCreatorArray.h
field/State.cc
field/State.h
field/detail/FieldImpl.cc
field/detail/FieldImpl.h
field/detail/FieldInterface.cc
field/detail/FieldInterface.h
field/detail/MultiFieldImpl.cc
field/detail/MultiFieldImpl.h
field/detail/MultiFieldInterface.cc
field/detail/MultiFieldInterface.h
field/detail/MissingValue.cc
field/detail/MissingValue.h
)
Expand Down Expand Up @@ -811,6 +823,8 @@ util/Topology.h
util/Allocate.h
util/Allocate.cc
util/GPUClonable.h
util/RegisterPointerInfo.cc
util/RegisterPointerInfo.h

util/Constants.h
util/ConvexSphericalPolygon.cc
Expand Down
26 changes: 26 additions & 0 deletions src/atlas/array/Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@
#include <memory>
#include <vector>

#include "eckit/config/Parametrisation.h"

#include "atlas/library/config.h"
#include "atlas/util/Config.h"

#include "atlas/util/Object.h"

#include "atlas/array/ArrayDataStore.h"
#include "atlas/array/DataType.h"
#include "atlas/array_fwd.h"

namespace eckit {
class Parametrisation;
}

namespace atlas {
namespace array {

Expand Down Expand Up @@ -85,12 +92,30 @@ class Array : public util::Object {

const ArrayStrides& strides() const { return spec_.strides(); }

const ArrayStrides& device_strides() const {
if( mapped_ ) {
return spec_.strides();
}
else {
return spec_.device_strides();
}
}

const ArrayShape& shape() const { return spec_.shape(); }

const std::vector<int>& shapef() const { return spec_.shapef(); }

const std::vector<int>& stridesf() const { return spec_.stridesf(); }

const std::vector<int>& device_stridesf() const {
if( mapped_ ) {
return spec_.stridesf();
}
else {
return spec_.device_stridesf();
}
}

bool contiguous() const { return spec_.contiguous(); }

bool hasDefaultLayout() const { return spec_.hasDefaultLayout(); }
Expand Down Expand Up @@ -190,6 +215,7 @@ class Array : public util::Object {
Array(ArraySpec&& spec): spec_(std::move(spec)) {}
ArraySpec spec_;
std::unique_ptr<ArrayDataStore> data_store_;
bool mapped_{false};

void replace(Array& array) {
data_store_.swap(array.data_store_);
Expand Down
2 changes: 1 addition & 1 deletion src/atlas/array/ArrayDataStore.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace atlas {
namespace array {

void throw_OutOfRange(const std::string& class_name, char idx_str, int idx, int max) {
void throw_OutOfRange(std::string_view class_name, char idx_str, int idx, int max) {
std::ostringstream msg;
msg << class_name << " index " << idx << " out of bounds: " << idx << " >= " << max;
throw_Exception(msg.str(), Here());
Expand Down
6 changes: 4 additions & 2 deletions src/atlas/array/ArrayDataStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

#pragma once

#include <string>
#include <string_view>

#include <eckit/config/Parametrisation.h>

#include "atlas/array/ArrayIdx.h"
#include "atlas/array/ArrayLayout.h"
Expand Down Expand Up @@ -81,7 +83,7 @@ static constexpr char array_dim() {
return Dim == 0 ? 'i' : (Dim == 1 ? 'j' : (Dim == 2 ? 'k' : (Dim == 3 ? 'l' : (Dim == 4 ? 'm' : ('*')))));
}

void throw_OutOfRange(const std::string& class_name, char idx_str, int idx, int max);
void throw_OutOfRange(std::string_view class_name, char idx_str, int idx, int max);
#endif

//------------------------------------------------------------------------------------------------------
Expand Down
16 changes: 16 additions & 0 deletions src/atlas/array/ArraySpec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,19 @@ ArraySpec::ArraySpec(const ArrayShape& shape, const ArrayAlignment& alignment):
rank_ = static_cast<int>(shape.size());
size_ = 1;
allocated_size_ = 1;
allocated_device_size_ = 1;
shape_.resize(rank_);
strides_.resize(rank_);
device_strides_.resize(rank_);
layout_.resize(rank_);
for (int j = rank_ - 1; j >= 0; --j) {
shape_[j] = shape[j];
strides_[j] = allocated_size_;
device_strides_[j] = allocated_device_size_;
layout_[j] = j;
size_ *= size_t(shape_[j]);
allocated_size_ *= size_t(aligned_shape[j]);
allocated_device_size_ *= size_t(shape[j]);
}
ATLAS_ASSERT(allocated_size_ == compute_aligned_size(size_t(shape_[0]) * size_t(strides_[0]), size_t(alignment)));
contiguous_ = (size_ == allocated_size_);
Expand Down Expand Up @@ -80,10 +84,12 @@ ArraySpec::ArraySpec(const ArrayShape& shape, const ArrayStrides& strides, const
size_ = 1;
shape_.resize(rank_);
strides_.resize(rank_);
device_strides_.resize(rank_);
layout_.resize(rank_);
for (int j = rank_ - 1; j >= 0; --j) {
shape_[j] = shape[j];
strides_[j] = strides[j];
device_strides_[j] = size_;
layout_[j] = j;
size_ *= size_t(shape_[j]);
}
Expand Down Expand Up @@ -120,11 +126,13 @@ ArraySpec::ArraySpec(const ArrayShape& shape, const ArrayStrides& strides, const
size_ = 1;
shape_.resize(rank_);
strides_.resize(rank_);
device_strides_.resize(rank_);
layout_.resize(rank_);
default_layout_ = true;
for (int j = rank_ - 1; j >= 0; --j) {
shape_[j] = shape[j];
strides_[j] = strides[j];
device_strides_[j] = size_;
layout_[j] = layout[j];
size_ *= size_t(shape_[j]);
if (layout_[j] != idx_t(j)) {
Expand All @@ -144,6 +152,7 @@ ArraySpec::ArraySpec(DataType datatype, const ArrayShape& shape, const ArrayStri
ArraySpec(shape, strides, layout, alignment) {
datatype_ = datatype;
}

const std::vector<int>& ArraySpec::shapef() const {
return shapef_;
}
Expand All @@ -152,12 +161,19 @@ const std::vector<int>& ArraySpec::stridesf() const {
return stridesf_;
}

const std::vector<int>& ArraySpec::device_stridesf() const {
return device_stridesf_;
}

void ArraySpec::allocate_fortran_specs() {
shapef_.resize(rank_);
stridesf_.resize(rank_);
device_stridesf_.resize(rank_);
device_stridesf_[rank_ - 1] = stridesf_[rank_ - 1];
for (idx_t j = 0; j < rank_; ++j) {
shapef_[j] = shape_[rank_ - 1 - layout_[j]];
stridesf_[j] = strides_[rank_ -1 - layout_[j]];
device_stridesf_[rank_ - j - 1] = device_stridesf_[rank_ - j] * shapef_[rank_ - j - 1];
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/atlas/array/ArraySpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ class ArraySpec {
size_t size_;
idx_t rank_;
size_t allocated_size_;
size_t allocated_device_size_;
DataType datatype_;
ArrayShape shape_;
ArrayStrides strides_;
ArrayStrides device_strides_;
ArrayLayout layout_;
ArrayAlignment alignment_;
std::vector<int> shapef_;
std::vector<int> stridesf_;
std::vector<int> device_stridesf_;
bool contiguous_;
bool default_layout_;

Expand All @@ -61,9 +64,11 @@ class ArraySpec {
const ArrayShape& shape() const { return shape_; }
const ArrayAlignment& alignment() const { return alignment_; }
const ArrayStrides& strides() const { return strides_; }
const ArrayStrides& device_strides() const { return device_strides_; }
const ArrayLayout& layout() const { return layout_; }
const std::vector<int>& shapef() const;
const std::vector<int>& stridesf() const;
const std::vector<int>& device_stridesf() const;
bool contiguous() const { return contiguous_; }
bool hasDefaultLayout() const { return default_layout_; }

Expand Down
1 change: 1 addition & 0 deletions src/atlas/array/ArrayStrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ArrayStrides : public std::vector<idx_t> {
ArrayStrides() {}
ArrayStrides(std::initializer_list<idx_t> list): Base(list) {}
ArrayStrides(Base&& base): Base(std::forward<Base>(base)) {}
ArrayStrides(const std::vector<idx_t>& list): Base(list.begin(), list.end()) {}
};

namespace detail {
Expand Down
3 changes: 3 additions & 0 deletions src/atlas/array/native/NativeArray.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@

#include <iostream>

//#include "eckit/config/Parametrisation.h"

#include "atlas/array.h"
#include "atlas/array/ArrayDataStore.h"
#include "atlas/array/MakeView.h"
#include "atlas/array/helpers/ArrayInitializer.h"
#include "atlas/array/helpers/ArrayWriter.h"
#include "atlas/array/native/NativeDataStore.h"
#include "atlas/util/Config.h"
#include "atlas/runtime/Exception.h"

using namespace atlas::array::helpers;
Expand Down
Loading
Loading