-
Notifications
You must be signed in to change notification settings - Fork 58
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
C++ Test #440
C++ Test #440
Changes from 8 commits
d11efa5
5e21c4e
c041729
4ad5247
4ed7ff6
c9c642c
9fc5f4e
5753793
60f3b19
a9d606e
6f999e3
bb9ae05
e723019
5c18c1b
448e5c8
99894b2
aa4d963
04bcb2d
53cb030
e820545
cb1a84a
d0f0d97
f7ad3f3
983631d
33513f1
2eae6ea
f6509ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,5 +6,16 @@ set -euo pipefail | |
# Support customizing the ctests' install location | ||
cd "${INSTALL_PREFIX:-${CONDA_PREFIX:-/usr}}/bin/tests/libkvikio/" | ||
|
||
# Run BASIC_IO_TEST | ||
./BASIC_IO_TEST | ||
# Run basic tests | ||
rapids-logger "Run BASIC_IO_EXAMPLE" | ||
./BASIC_IO_EXAMPLE | ||
rapids-logger "Run BASIC_NO_CUDA_EXAMPLE" | ||
./BASIC_NO_CUDA_EXAMPLE | ||
|
||
# Run gtests | ||
rapids-logger "Run gtests" | ||
./cpp_tests | ||
# TODO: how to use ctest instead of executing the test directly? | ||
# The following line fails with a "ctest doesn't exist" in CI. | ||
# Do we need to install ctest in the CI images? | ||
# ctest --no-tests=error --output-on-failure "$@" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to install There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to install cmake. Add to the test_cpp group. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, fixed |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# ============================================================================= | ||
# Copyright (c) 2024, NVIDIA CORPORATION. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
# in compliance with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under the License | ||
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
# or implied. See the License for the specific language governing permissions and limitations under | ||
# the License. | ||
# ============================================================================= | ||
|
||
# ################################################################################################## | ||
# enable testing ----------------------------------------------------------------------------------- | ||
# ################################################################################################## | ||
enable_testing() | ||
|
||
include(rapids-test) | ||
|
||
file(GLOB SOURCES "*.cpp") | ||
add_executable(cpp_tests ${SOURCES}) | ||
set_target_properties( | ||
cpp_tests | ||
PROPERTIES RUNTIME_OUTPUT_DIRECTORY "$<BUILD_INTERFACE:${KvikIO_BINARY_DIR}/gtests>" | ||
CXX_STANDARD 17 | ||
CXX_STANDARD_REQUIRED ON | ||
# For std:: support of __int128_t. Can be removed once using cuda::std | ||
CXX_EXTENSIONS ON | ||
CUDA_STANDARD 17 | ||
CUDA_STANDARD_REQUIRED ON | ||
) | ||
target_link_libraries(cpp_tests PRIVATE kvikio::kvikio GTest::gmock GTest::gtest) | ||
rapids_test_add( | ||
NAME cpp_tests | ||
COMMAND cpp_tests | ||
INSTALL_COMPONENT_SET testing | ||
) | ||
|
||
rapids_test_install_relocatable(INSTALL_COMPONENT_SET testing DESTINATION bin/tests/libkvikio) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Copyright (c) 2024, NVIDIA CORPORATION. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <gtest/gtest.h> | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
::testing::InitGoogleTest(&argc, argv); | ||
return RUN_ALL_TESTS(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
* Copyright (c) 2024, NVIDIA CORPORATION. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <kvikio/file_handle.hpp> | ||
|
||
#include "utils.hpp" | ||
|
||
using namespace kvikio::test; | ||
|
||
TEST(BasicIO, write_read) | ||
{ | ||
TempDir tmp_dir{false}; | ||
auto filepath = tmp_dir.path() / "test"; | ||
|
||
auto dev_a = DevBuffer::arange(100); | ||
auto dev_b = DevBuffer::zero_like(dev_a); | ||
|
||
{ | ||
kvikio::FileHandle f(filepath, "w"); | ||
auto nbytes = f.write(dev_a.ptr, dev_a.nbytes, 0, 0); | ||
EXPECT_EQ(nbytes, dev_a.nbytes); | ||
} | ||
|
||
{ | ||
kvikio::FileHandle f(filepath, "r"); | ||
auto nbytes = f.read(dev_b.ptr, dev_b.nbytes, 0, 0); | ||
EXPECT_EQ(nbytes, dev_b.nbytes); | ||
expect_equal(dev_a, dev_b); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* Copyright (c) 2024, NVIDIA CORPORATION. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
#include <filesystem> | ||
#include <iostream> | ||
#include <numeric> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <cuda_runtime_api.h> | ||
#include <gtest/gtest.h> | ||
|
||
#include <kvikio/error.hpp> | ||
|
||
namespace kvikio::test { | ||
|
||
/** \ | ||
* @brief Error checking macro for CUDA runtime API functions. \ | ||
* \ | ||
* Invokes a CUDA runtime API function call. If the call does not return \ | ||
* `cudaSuccess`, invokes cudaGetLastError() to clear the error and throws an \ | ||
* exception detailing the CUDA error that occurred \ | ||
* \ | ||
* Defaults to throwing std::runtime_error, but a custom exception may also be \ | ||
* specified. \ | ||
* \ | ||
* Example: \ | ||
* ```c++ \ | ||
* \ | ||
* // Throws std::runtime_error if `cudaMalloc` fails \ | ||
* KVIKIO_CHECK_CUDA(cudaMalloc(&p, 100)); \ | ||
* \ | ||
* // Throws std::runtime_error if `cudaMalloc` fails \ | ||
* KVIKIO_CHECK_CUDA(cudaMalloc(&p, 100), std::runtime_error); \ | ||
* ``` \ | ||
* \ | ||
*/ \ | ||
#define KVIKIO_CHECK_CUDA(...) \ | ||
GET_KVIKIO_CHECK_CUDA_MACRO(__VA_ARGS__, KVIKIO_CHECK_CUDA_2, KVIKIO_CHECK_CUDA_1) \ | ||
(__VA_ARGS__) | ||
#define GET_KVIKIO_CHECK_CUDA_MACRO(_1, _2, NAME, ...) NAME | ||
#define KVIKIO_CHECK_CUDA_2(_call, _exception_type) \ | ||
do { \ | ||
cudaError_t const error = (_call); \ | ||
if (cudaSuccess != error) { \ | ||
cudaGetLastError(); \ | ||
/*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \ | ||
throw _exception_type{std::string{"CUDA error at: "} + __FILE__ + ":" + \ | ||
KVIKIO_STRINGIFY(__LINE__) + ": " + cudaGetErrorName(error) + " " + \ | ||
cudaGetErrorString(error)}; \ | ||
} \ | ||
} while (0) | ||
#define KVIKIO_CHECK_CUDA_1(_call) KVIKIO_CHECK_CUDA_2(_call, std::runtime_error) | ||
|
||
/** | ||
* @brief Help class to create a temporary directory. | ||
*/ | ||
class TempDir { | ||
public: | ||
TempDir(const bool cleanup = true) : _cleanup{cleanup} | ||
{ | ||
std::string tpl{std::filesystem::temp_directory_path() / "legate-dataframe.XXXXXX"}; | ||
madsbk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (mkdtemp(tpl.data()) == nullptr) { | ||
throw std::runtime_error("TempDir: cannot make tmpdir: " + tpl); | ||
} | ||
_dir_path = tpl; | ||
} | ||
~TempDir() noexcept | ||
{ | ||
if (_cleanup) { | ||
try { | ||
std::filesystem::remove_all(_dir_path); | ||
} catch (...) { | ||
std::cout << "error while trying to remove " << _dir_path.string() << std::endl; | ||
} | ||
} | ||
} | ||
|
||
TempDir(const TempDir&) = delete; | ||
TempDir& operator=(TempDir const&) = delete; | ||
TempDir(const TempDir&&) = delete; | ||
TempDir&& operator=(TempDir const&&) = delete; | ||
|
||
const std::filesystem::path& path() { return _dir_path; } | ||
|
||
operator std::string() { return path(); } | ||
|
||
private: | ||
const bool _cleanup; | ||
std::filesystem::path _dir_path{}; | ||
}; | ||
|
||
/** | ||
* @brief Help class for creating and comparing buffers. | ||
*/ | ||
class DevBuffer { | ||
public: | ||
const std::size_t nelem; | ||
const std::size_t nbytes; | ||
void* ptr{nullptr}; | ||
|
||
DevBuffer(std::size_t nelem) : nelem{nelem}, nbytes{nelem * sizeof(std::int64_t)} | ||
{ | ||
KVIKIO_CHECK_CUDA(cudaMalloc(&ptr, nbytes)); | ||
} | ||
DevBuffer(const std::vector<std::int64_t>& host_buffer) : DevBuffer{host_buffer.size()} | ||
{ | ||
KVIKIO_CHECK_CUDA(cudaMemcpy(ptr, host_buffer.data(), nbytes, cudaMemcpyHostToDevice)); | ||
} | ||
|
||
~DevBuffer() noexcept { cudaFree(ptr); } | ||
|
||
[[nodiscard]] static DevBuffer arange(std::size_t nelem, std::int64_t start = 0) | ||
{ | ||
std::vector<std::int64_t> host_buffer(nelem); | ||
std::iota(host_buffer.begin(), host_buffer.end(), start); | ||
return DevBuffer{host_buffer}; | ||
} | ||
|
||
[[nodiscard]] static DevBuffer zero_like(const DevBuffer& prototype) | ||
{ | ||
DevBuffer ret{prototype.nelem}; | ||
KVIKIO_CHECK_CUDA(cudaMemset(ret.ptr, 0, ret.nbytes)); | ||
return ret; | ||
} | ||
|
||
[[nodiscard]] std::vector<std::int64_t> to_vector() const | ||
{ | ||
std::vector<std::int64_t> ret(nelem); | ||
KVIKIO_CHECK_CUDA(cudaMemcpy(ret.data(), this->ptr, nbytes, cudaMemcpyDeviceToHost)); | ||
return ret; | ||
} | ||
|
||
void pprint() const | ||
{ | ||
std::cout << "DevBuffer("; | ||
for (auto item : to_vector()) { | ||
std::cout << (int64_t)item << ", "; | ||
madsbk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
std::cout << ")" << std::endl; | ||
} | ||
}; | ||
|
||
/** | ||
* @brief Check that two buffers are equal | ||
*/ | ||
inline void expect_equal(const DevBuffer& a, const DevBuffer& b) | ||
{ | ||
EXPECT_EQ(a.nbytes, b.nbytes); | ||
auto a_vec = a.to_vector(); | ||
auto b_vec = b.to_vector(); | ||
for (std::size_t i = 0; i < a.nelem; ++i) { | ||
EXPECT_EQ(a_vec[i], b_vec[i]) << "Mismatch at index #" << i; | ||
madsbk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
} // namespace kvikio::test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a weak preference to avoid
rapids-logger
commands in therun_*.sh
scripts because I think those are intended for reuse outside of the CI workflows (in DLFW, perhaps?). In other use cases, thegha-tools
utilities may not be present. Either useecho
or replace therapids-logger
statements with code comments.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@trxcllnt may have comments about appropriate use cases here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed the rapids-logger use