Skip to content

Commit a00842f

Browse files
jtrammJohn Tramm
authored andcommitted
Replace xtensor with internal Tensor/View classes (#3805)
Co-authored-by: John Tramm <jtramm@gmail.com>
1 parent d4b973c commit a00842f

73 files changed

Lines changed: 3155 additions & 936 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitmodules

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
[submodule "vendor/pugixml"]
22
path = vendor/pugixml
33
url = https://github.com/zeux/pugixml.git
4-
[submodule "vendor/xtensor"]
5-
path = vendor/xtensor
6-
url = https://github.com/xtensor-stack/xtensor.git
7-
[submodule "vendor/xtl"]
8-
path = vendor/xtl
9-
url = https://github.com/xtensor-stack/xtl.git
104
[submodule "vendor/fmt"]
115
path = vendor/fmt
126
url = https://github.com/fmtlib/fmt.git

CMakeLists.txt

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -266,23 +266,6 @@ else()
266266
endif()
267267
endif()
268268

269-
#===============================================================================
270-
# xtensor header-only library
271-
#===============================================================================
272-
273-
if(OPENMC_FORCE_VENDORED_LIBS)
274-
add_subdirectory(vendor/xtl)
275-
set(xtl_DIR ${CMAKE_CURRENT_BINARY_DIR}/vendor/xtl)
276-
add_subdirectory(vendor/xtensor)
277-
else()
278-
find_package_write_status(xtensor)
279-
if (NOT xtensor_FOUND)
280-
add_subdirectory(vendor/xtl)
281-
set(xtl_DIR ${CMAKE_CURRENT_BINARY_DIR}/vendor/xtl)
282-
add_subdirectory(vendor/xtensor)
283-
endif()
284-
endif()
285-
286269
#===============================================================================
287270
# Catch2 library
288271
#===============================================================================
@@ -495,7 +478,7 @@ endif()
495478
# target_link_libraries treats any arguments starting with - but not -l as
496479
# linker flags. Thus, we can pass both linker flags and libraries together.
497480
target_link_libraries(libopenmc ${ldflags} ${HDF5_LIBRARIES} ${HDF5_HL_LIBRARIES}
498-
xtensor fmt::fmt ${CMAKE_DL_LIBS})
481+
fmt::fmt ${CMAKE_DL_LIBS})
499482

500483
if(TARGET pugixml::pugixml)
501484
target_link_libraries(libopenmc pugixml::pugixml)

cmake/OpenMCConfig.cmake.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ get_filename_component(_OPENMC_PREFIX "${OpenMC_CMAKE_DIR}/../../.." ABSOLUTE)
55

66
find_package(fmt CONFIG REQUIRED HINTS ${_OPENMC_PREFIX})
77
find_package(pugixml CONFIG REQUIRED HINTS ${_OPENMC_PREFIX})
8-
find_package(xtl CONFIG REQUIRED HINTS ${_OPENMC_PREFIX})
9-
find_package(xtensor CONFIG REQUIRED HINTS ${_OPENMC_PREFIX})
108
if(@OPENMC_USE_DAGMC@)
119
find_package(DAGMC REQUIRED HINTS @DAGMC_DIR@)
1210
endif()

docs/source/quickinstall.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ packages should be installed, for example in Homebrew via:
119119

120120
.. code-block:: sh
121121
122-
brew install llvm cmake xtensor hdf5 python libomp libpng
122+
brew install llvm cmake hdf5 python libomp libpng
123123
124124
The compiler provided by the above LLVM package should be used in place of the
125125
one provisioned by XCode, which does not support the multithreading library used

include/openmc/bremsstrahlung.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include "openmc/particle.h"
55

6-
#include "xtensor/xtensor.hpp"
6+
#include "openmc/tensor.h"
77

88
namespace openmc {
99

@@ -14,9 +14,9 @@ namespace openmc {
1414
class BremsstrahlungData {
1515
public:
1616
// Data
17-
xt::xtensor<double, 2> pdf; //!< Bremsstrahlung energy PDF
18-
xt::xtensor<double, 2> cdf; //!< Bremsstrahlung energy CDF
19-
xt::xtensor<double, 1> yield; //!< Photon yield
17+
tensor::Tensor<double> pdf; //!< Bremsstrahlung energy PDF
18+
tensor::Tensor<double> cdf; //!< Bremsstrahlung energy CDF
19+
tensor::Tensor<double> yield; //!< Photon yield
2020
};
2121

2222
class Bremsstrahlung {
@@ -32,9 +32,9 @@ class Bremsstrahlung {
3232

3333
namespace data {
3434

35-
extern xt::xtensor<double, 1>
35+
extern tensor::Tensor<double>
3636
ttb_e_grid; //! energy T of incident electron in [eV]
37-
extern xt::xtensor<double, 1>
37+
extern tensor::Tensor<double>
3838
ttb_k_grid; //! reduced energy W/T of emitted photon
3939

4040
} // namespace data

include/openmc/distribution_energy.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#define OPENMC_DISTRIBUTION_ENERGY_H
66

77
#include "hdf5.h"
8-
#include "xtensor/xtensor.hpp"
8+
#include "openmc/tensor.h"
99

1010
#include "openmc/constants.h"
1111
#include "openmc/endf.h"
@@ -86,9 +86,9 @@ class ContinuousTabular : public EnergyDistribution {
8686
struct CTTable {
8787
Interpolation interpolation; //!< Interpolation law
8888
int n_discrete; //!< Number of of discrete energies
89-
xt::xtensor<double, 1> e_out; //!< Outgoing energies in [eV]
90-
xt::xtensor<double, 1> p; //!< Probability density
91-
xt::xtensor<double, 1> c; //!< Cumulative distribution
89+
tensor::Tensor<double> e_out; //!< Outgoing energies in [eV]
90+
tensor::Tensor<double> p; //!< Probability density
91+
tensor::Tensor<double> c; //!< Cumulative distribution
9292
};
9393

9494
int n_region_; //!< Number of inteprolation regions

include/openmc/eigenvalue.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#include <cstdint> // for int64_t
88

9-
#include "xtensor/xtensor.hpp"
9+
#include "openmc/tensor.h"
1010
#include <hdf5.h>
1111

1212
#include "openmc/array.h"
@@ -24,7 +24,7 @@ namespace simulation {
2424
extern double keff_generation; //!< Single-generation k on each processor
2525
extern array<double, 2> k_sum; //!< Used to reduce sum and sum_sq
2626
extern vector<double> entropy; //!< Shannon entropy at each generation
27-
extern xt::xtensor<double, 1> source_frac; //!< Source fraction for UFS
27+
extern tensor::Tensor<double> source_frac; //!< Source fraction for UFS
2828

2929
} // namespace simulation
3030

include/openmc/hdf5_interface.h

Lines changed: 34 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111

1212
#include "hdf5.h"
1313
#include "hdf5_hl.h"
14-
#include "xtensor/xadapt.hpp"
15-
#include "xtensor/xarray.hpp"
14+
#include "openmc/tensor.h"
1615

1716
#include "openmc/array.h"
1817
#include "openmc/error.h"
@@ -166,24 +165,19 @@ void read_attribute(hid_t obj_id, const char* name, vector<T>& vec)
166165
read_attr(obj_id, name, H5TypeMap<T>::type_id, vec.data());
167166
}
168167

169-
// Generic array version
168+
// Tensor version
170169
template<typename T>
171-
void read_attribute(hid_t obj_id, const char* name, xt::xarray<T>& arr)
170+
void read_attribute(hid_t obj_id, const char* name, tensor::Tensor<T>& tensor)
172171
{
173-
// Get shape of attribute array
172+
// Get shape of attribute
174173
auto shape = attribute_shape(obj_id, name);
175174

176-
// Allocate new array to read data into
177-
std::size_t size = 1;
178-
for (const auto x : shape)
179-
size *= x;
180-
vector<T> buffer(size);
175+
// Resize tensor and read data directly
176+
vector<size_t> tshape(shape.begin(), shape.end());
177+
tensor.resize(tshape);
181178

182179
// Read data from attribute
183-
read_attr(obj_id, name, H5TypeMap<T>::type_id, buffer.data());
184-
185-
// Adapt array into xarray
186-
arr = xt::adapt(buffer, shape);
180+
read_attr(obj_id, name, H5TypeMap<T>::type_id, tensor.data());
187181
}
188182

189183
// overload for std::string
@@ -290,61 +284,32 @@ void read_dataset(
290284
}
291285

292286
template<typename T>
293-
void read_dataset(hid_t dset, xt::xarray<T>& arr, bool indep = false)
287+
void read_dataset(hid_t dset, tensor::Tensor<T>& tensor, bool indep = false)
294288
{
295289
// Get shape of dataset
296290
vector<hsize_t> shape = object_shape(dset);
297291

298-
// Allocate space in the array to read data into
299-
std::size_t size = 1;
300-
for (const auto x : shape)
301-
size *= x;
302-
arr.resize(shape);
292+
// Resize tensor and read data directly
293+
vector<size_t> tshape(shape.begin(), shape.end());
294+
tensor.resize(tshape);
303295

304-
// Read data from attribute
296+
// Read data from dataset
305297
read_dataset_lowlevel(
306-
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, arr.data());
298+
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, tensor.data());
307299
}
308300

309301
template<>
310302
void read_dataset(
311-
hid_t dset, xt::xarray<std::complex<double>>& arr, bool indep);
303+
hid_t dset, tensor::Tensor<std::complex<double>>& tensor, bool indep);
312304

313305
template<typename T>
314306
void read_dataset(
315-
hid_t obj_id, const char* name, xt::xarray<T>& arr, bool indep = false)
316-
{
317-
// Open dataset and read array
318-
hid_t dset = open_dataset(obj_id, name);
319-
read_dataset(dset, arr, indep);
320-
close_dataset(dset);
321-
}
322-
323-
template<typename T, std::size_t N>
324-
void read_dataset(
325-
hid_t obj_id, const char* name, xt::xtensor<T, N>& arr, bool indep = false)
307+
hid_t obj_id, const char* name, tensor::Tensor<T>& tensor, bool indep = false)
326308
{
327-
// Open dataset and read array
309+
// Open dataset and read tensor
328310
hid_t dset = open_dataset(obj_id, name);
329-
330-
// Get shape of dataset
331-
vector<hsize_t> hsize_t_shape = object_shape(dset);
311+
read_dataset(dset, tensor, indep);
332312
close_dataset(dset);
333-
334-
// cast from hsize_t to size_t
335-
vector<size_t> shape(hsize_t_shape.size());
336-
for (int i = 0; i < shape.size(); i++) {
337-
shape[i] = static_cast<size_t>(hsize_t_shape[i]);
338-
}
339-
340-
// Allocate new xarray to read data into
341-
xt::xarray<T> xarr(shape);
342-
343-
// Read data from the dataset
344-
read_dataset(obj_id, name, xarr);
345-
346-
// Copy into xtensor
347-
arr = xarr;
348313
}
349314

350315
// overload for Position
@@ -358,31 +323,22 @@ inline void read_dataset(
358323
r.z = x[2];
359324
}
360325

361-
template<typename T, std::size_t N>
326+
template<typename T>
362327
inline void read_dataset_as_shape(
363-
hid_t obj_id, const char* name, xt::xtensor<T, N>& arr, bool indep = false)
328+
hid_t obj_id, const char* name, tensor::Tensor<T>& tensor, bool indep = false)
364329
{
365330
hid_t dset = open_dataset(obj_id, name);
366331

367-
// Allocate new array to read data into
368-
std::size_t size = 1;
369-
for (const auto x : arr.shape())
370-
size *= x;
371-
vector<T> buffer(size);
372-
373-
// Read data from attribute
332+
// Read data directly into pre-shaped tensor
374333
read_dataset_lowlevel(
375-
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, buffer.data());
376-
377-
// Adapt into xarray
378-
arr = xt::adapt(buffer, arr.shape());
334+
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, tensor.data());
379335

380336
close_dataset(dset);
381337
}
382338

383-
template<typename T, std::size_t N>
384-
inline void read_nd_vector(hid_t obj_id, const char* name,
385-
xt::xtensor<T, N>& result, bool must_have = false)
339+
template<typename T>
340+
inline void read_nd_tensor(hid_t obj_id, const char* name,
341+
tensor::Tensor<T>& result, bool must_have = false)
386342
{
387343
if (object_exists(obj_id, name)) {
388344
read_dataset_as_shape(obj_id, name, result, true);
@@ -496,12 +452,16 @@ inline void write_dataset(
496452
false, buffer.data());
497453
}
498454

499-
// Template for xarray, xtensor, etc.
500-
template<typename D>
501-
inline void write_dataset(
502-
hid_t obj_id, const char* name, const xt::xcontainer<D>& arr)
455+
// Template for Tensor and StaticTensor2D. A SFINAE guard is used here to
456+
// prevent this template from matching vector/string types that have their own
457+
// overloads above. A generic Container parameter avoids duplicating the body
458+
// for both Tensor<T> and StaticTensor2D<T,R,C>.
459+
template<typename Container,
460+
typename =
461+
std::enable_if_t<tensor::is_tensor<std::decay_t<Container>>::value>>
462+
inline void write_dataset(hid_t obj_id, const char* name, const Container& arr)
503463
{
504-
using T = typename D::value_type;
464+
using T = typename std::decay_t<Container>::value_type;
505465
auto s = arr.shape();
506466
vector<hsize_t> dims {s.cbegin(), s.cend()};
507467
write_dataset_lowlevel(obj_id, dims.size(), dims.data(), name,

include/openmc/material.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#include <unordered_map>
66

77
#include "openmc/span.h"
8+
#include "openmc/tensor.h"
89
#include "pugixml.hpp"
9-
#include "xtensor/xtensor.hpp"
1010
#include <hdf5.h>
1111

1212
#include "openmc/bremsstrahlung.h"
@@ -189,7 +189,7 @@ class Material {
189189
vector<int> nuclide_; //!< Indices in nuclides vector
190190
vector<int> element_; //!< Indices in elements vector
191191
NCrystalMat ncrystal_mat_; //!< NCrystal material object
192-
xt::xtensor<double, 1> atom_density_; //!< Nuclide atom density in [atom/b-cm]
192+
tensor::Tensor<double> atom_density_; //!< Nuclide atom density in [atom/b-cm]
193193
double density_; //!< Total atom density in [atom/b-cm]
194194
double density_gpcc_; //!< Total atom density in [g/cm^3]
195195
double charge_density_; //!< Total charge density in [e/b-cm]

include/openmc/mesh.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#include <unordered_map>
99

1010
#include "hdf5.h"
11+
#include "openmc/tensor.h"
1112
#include "pugixml.hpp"
12-
#include "xtensor/xtensor.hpp"
1313

1414
#include "openmc/bounding_box.h"
1515
#include "openmc/error.h"
@@ -252,8 +252,8 @@ class Mesh {
252252
virtual Position upper_right() const = 0;
253253

254254
// Data members
255-
xt::xtensor<double, 1> lower_left_; //!< Lower-left coordinates of mesh
256-
xt::xtensor<double, 1> upper_right_; //!< Upper-right coordinates of mesh
255+
tensor::Tensor<double> lower_left_; //!< Lower-left coordinates of mesh
256+
tensor::Tensor<double> upper_right_; //!< Upper-right coordinates of mesh
257257
int id_ {-1}; //!< Mesh ID
258258
std::string name_; //!< User-specified name
259259
int n_dimension_ {-1}; //!< Number of dimensions
@@ -316,7 +316,7 @@ class StructuredMesh : public Mesh {
316316
//! \param[in] Pointer to bank sites
317317
//! \param[in] Number of bank sites
318318
//! \param[out] Whether any bank sites are outside the mesh
319-
xt::xtensor<double, 1> count_sites(
319+
tensor::Tensor<double> count_sites(
320320
const SourceSite* bank, int64_t length, bool* outside) const;
321321

322322
//! Get bin given mesh indices
@@ -387,8 +387,8 @@ class StructuredMesh : public Mesh {
387387
//! Get a label for the mesh bin
388388
std::string bin_label(int bin) const override;
389389

390-
//! Get shape as xt::xtensor
391-
xt::xtensor<int, 1> get_x_shape() const;
390+
//! Get mesh dimensions as a tensor
391+
tensor::Tensor<int> get_shape_tensor() const;
392392

393393
double volume(int bin) const override
394394
{
@@ -483,7 +483,7 @@ class RegularMesh : public StructuredMesh {
483483
//! \param[in] bank Array of bank sites
484484
//! \param[out] Whether any bank sites are outside the mesh
485485
//! \return Array indicating number of sites in each mesh/energy bin
486-
xt::xtensor<double, 1> count_sites(
486+
tensor::Tensor<double> count_sites(
487487
const SourceSite* bank, int64_t length, bool* outside) const;
488488

489489
//! Return the volume for a given mesh index
@@ -494,7 +494,7 @@ class RegularMesh : public StructuredMesh {
494494
// Data members
495495
double volume_frac_; //!< Volume fraction of each mesh element
496496
double element_volume_; //!< Volume of each mesh element
497-
xt::xtensor<double, 1> width_; //!< Width of each mesh element
497+
tensor::Tensor<double> width_; //!< Width of each mesh element
498498
};
499499

500500
class RectilinearMesh : public StructuredMesh {

0 commit comments

Comments
 (0)