1 /*************************************************************************** 2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * 3 * Copyright (c) QuantStack * 4 * * 5 * Distributed under the terms of the BSD 3-Clause License. * 6 * * 7 * The full license is in the file LICENSE, distributed with this software. * 8 ****************************************************************************/ 9 10 #include "test_common_macros.hpp" 11 12 #include "xtensor/xnpy.hpp" 13 #include "xtensor/xarray.hpp" 14 15 #include <fstream> 16 #include <cstdint> 17 18 namespace xt 19 { get_load_filename(std::string const & npy_prefix,layout_type lt=layout_type::row_major)20 std::string get_load_filename(std::string const& npy_prefix, layout_type lt = layout_type::row_major) 21 { 22 std::string lts = lt == layout_type::row_major ? "" : "_fortran"; 23 std::string endianness; 24 switch(xtl::endianness()) 25 { 26 case xtl::endian::big_endian: 27 endianness = ".be"; 28 break; 29 case xtl::endian::little_endian: 30 endianness = ".le"; 31 break; 32 case xtl::endian::mixed: 33 endianness = ".unsupported"; 34 break; 35 } 36 return npy_prefix + lts + endianness + ".npy"; 37 } 38 TEST(xnpy,load)39 TEST(xnpy, load) 40 { 41 xarray<double> darr = {{{ 0.29731723, 0.04380157, 0.94748308}, 42 { 0.85020643, 0.52958618, 0.0598172 }, 43 { 0.77253259, 0.47564231, 0.70274005}}, 44 {{ 0.85998447, 0.61160158, 0.44432939}, 45 { 0.25506765, 0.97420976, 0.15455842}, 46 { 0.05873659, 0.66191764, 0.01448838}}, 47 {{ 0.175919 , 0.13850365, 0.94059426}, 48 { 0.79941809, 0.5124432 , 0.51364796}, 49 { 0.25721979, 0.41608858, 0.06255319}}}; 50 51 xarray<bool> barr = {{{ 0, 0, 1}, 52 { 1, 1, 0}, 53 { 1, 0, 1}}, 54 {{ 1, 1, 0}, 55 { 0, 1, 0}, 56 { 0, 1, 0}}, 57 {{ 0, 0, 1}, 58 { 1, 1, 1}, 59 { 0, 0, 0}}}; 60 61 xarray<int> iarr1d = {3, 4, 5, 6, 7}; 62 63 auto darr_loaded = load_npy<double>(get_load_filename("files/xnpy_files/double")); 64 EXPECT_TRUE(all(isclose(darr, darr_loaded))); 65 66 std::ifstream dstream(get_load_filename("files/xnpy_files/double")); 67 auto darr_loaded_stream = load_npy<double>(dstream); 68 CHECK_MESSAGE(all(isclose(darr, darr_loaded_stream)),"Loading double numpy array from stream failed"); 69 dstream.close(); 70 71 auto barr_loaded = load_npy<bool>(get_load_filename("files/xnpy_files/bool")); 72 EXPECT_TRUE(all(equal(barr, barr_loaded))); 73 74 std::ifstream bstream(get_load_filename("files/xnpy_files/bool")); 75 auto barr_loaded_stream = load_npy<bool>(bstream); 76 CHECK_MESSAGE(all(equal(barr, barr_loaded_stream)),"Loading boolean numpy array from stream failed"); 77 bstream.close(); 78 79 auto dfarr_loaded = load_npy<double, layout_type::column_major>(get_load_filename("files/xnpy_files/double_fortran")); 80 EXPECT_TRUE(all(isclose(darr, dfarr_loaded))); 81 82 auto iarr1d_loaded = load_npy<int>(get_load_filename("files/xnpy_files/int")); 83 EXPECT_TRUE(all(equal(iarr1d, iarr1d_loaded))); 84 } 85 compare_binary_files(std::string fn1,std::string fn2)86 bool compare_binary_files(std::string fn1, std::string fn2) 87 { 88 std::ifstream stream1(fn1, std::ios::in | std::ios::binary); 89 std::vector<uint8_t> fn1_contents((std::istreambuf_iterator<char>(stream1)), 90 std::istreambuf_iterator<char>()); 91 92 std::ifstream stream2(fn2, std::ios::in | std::ios::binary); 93 std::vector<uint8_t> fn2_contents((std::istreambuf_iterator<char>(stream2)), 94 std::istreambuf_iterator<char>()); 95 return std::equal(fn1_contents.begin(), fn1_contents.end(), fn2_contents.begin()) && 96 fn1_contents.size() == fn2_contents.size(); 97 } 98 99 get_dump_filename(int n)100 std::string get_dump_filename(int n) 101 { 102 std::string filename = "files/xnpy_files/test_dump_" + std::to_string(n) + ".npy"; 103 return filename; 104 } 105 read_file(const std::string & name)106 std::string read_file(const std::string& name) 107 { 108 return static_cast<std::stringstream const&>(std::stringstream() << std::ifstream(name).rdbuf()).str(); 109 } 110 TEST(xnpy,dump)111 TEST(xnpy, dump) 112 { 113 std::string filename = get_dump_filename(0); 114 xarray<bool> barr = {{{0, 0, 1}, 115 {1, 1, 0}, 116 {1, 0, 1}}, 117 {{1, 1, 0}, 118 {0, 1, 0}, 119 {0, 1, 0}}, 120 {{0, 0, 1}, 121 {1, 1, 1}, 122 {0, 0, 0}}}; 123 124 xtensor<uint64_t, 1> ularr = {12ul, 14ul, 16ul, 18ul, 1234321ul}; 125 dump_npy(filename, barr); 126 127 std::string compare_name = get_load_filename("files/xnpy_files/bool", barr.layout()); 128 129 EXPECT_TRUE(compare_binary_files(filename, compare_name)); 130 131 std::string barr_str = dump_npy(barr); 132 std::string barr_disk = read_file(compare_name); 133 CHECK_MESSAGE(barr_str==barr_disk,"Dumping boolean numpy file to string failed"); 134 135 std::remove(filename.c_str()); 136 137 filename = get_dump_filename(1); 138 dump_npy(filename, ularr); 139 auto ularrcpy = load_npy<uint64_t>(filename); 140 EXPECT_TRUE(all(equal(ularr, ularrcpy))); 141 142 compare_name = get_load_filename("files/xnpy_files/unsignedlong", barr.layout()); 143 144 EXPECT_TRUE(compare_binary_files(filename, compare_name)); 145 146 std::string ularr_str = dump_npy(ularr); 147 std::string ularr_disk = read_file(compare_name); 148 CHECK_MESSAGE(ularr_str==ularr_disk,"Dumping boolean numpy file to string failed"); 149 150 std::remove(filename.c_str()); 151 } 152 TEST(xnpy,xfunction_cast)153 TEST(xnpy, xfunction_cast) 154 { 155 // compilation test, cf: https://github.com/xtensor-stack/xtensor/issues/1070 156 auto dc = cast<char>(load_npy<double>(get_load_filename("files/xnpy_files/double"))); 157 EXPECT_EQ(dc(0, 0), 0); 158 xarray<char> adc = dc; 159 EXPECT_EQ(adc(0, 0), 0); 160 } 161 } 162