pfor/tests/internal/rwcontrol.cpp

89 lines
3.5 KiB
C++

#include <catch.hpp>
#include "../common.h"
#include <pfor/parallelizable.h>
#include <pfor/index/operators.h>
TEST_CASE("RWControl") {
constexpr pfor::expr::Access R = pfor::expr::Access::read, W = pfor::expr::Access::write;
pfor::Index it;
using OT1R = pfor::expr::OperandTag<class ID1, R, pfor::Index>;
using OT2R = pfor::expr::OperandTag<class ID2, R, pfor::Index>;
using OT3R = pfor::expr::OperandTag<class ID3, R, pfor::Index>;
using OT1W = pfor::expr::OperandTag<class ID1, W, pfor::Index>;
using OT2W = pfor::expr::OperandTag<class ID2, W, pfor::Index>;
using OT3W = pfor::expr::OperandTag<class ID3, W, pfor::Index>;
using Tags1R = pfor::Pack<OT1R>;
using Tags1R2R = pfor::Pack<OT1R, OT2R>;
using Tags1R2R3R = pfor::Pack<OT1R, OT2R, OT3R>;
using Tags1W2R = pfor::Pack<OT1W, OT2R>;
using Tags1W1R2R = pfor::Pack<OT1W, OT1R, OT2R>;
using Tags1W1R2R3R = pfor::Pack<OT1W, OT1R, OT2R, OT3R>;
using Tags1W2W3R3R = pfor::Pack<OT1W, OT2W, OT3R, OT3R>;
using Tags1R2W3W3R = pfor::Pack<OT1R, OT2W, OT3W, OT3R>;
using Tags1R2W3R3R = pfor::Pack<OT1R, OT2W, OT3R, OT3R>;
SECTION("RWControl") {
SECTION("Constant index") {
using C0 = decltype(pfor::ctv<0>);
using TagsW = pfor::Pack<pfor::expr::OperandTag<class ID0, W, C0>>;
using TagsR = pfor::Pack<pfor::expr::OperandTag<class ID0, R, C0>>;
using TagsRW = pfor::Pack<pfor::expr::OperandTag<class ID0, R, C0>, pfor::expr::OperandTag<class ID0, W, C0>>;
REQUIRE_FALSE(pfor::rwControl<TagsW>);
REQUIRE(pfor::rwControl<TagsR>);
REQUIRE_FALSE(pfor::rwControl<TagsRW>);
}
SECTION("Same index") {
REQUIRE(pfor::rwControl<Tags1R>);
REQUIRE(pfor::rwControl<Tags1R2R>);
REQUIRE(pfor::rwControl<Tags1R2R>);
REQUIRE(pfor::rwControl<Tags1R2R3R>);
REQUIRE(pfor::rwControl<Tags1W2R>);
REQUIRE(pfor::rwControl<Tags1W1R2R>);
REQUIRE(pfor::rwControl<Tags1W1R2R3R>);
REQUIRE(pfor::rwControl<Tags1W2W3R3R>);
REQUIRE(pfor::rwControl<Tags1R2W3W3R>);
REQUIRE(pfor::rwControl<Tags1R2W3R3R>);
}
SECTION("Different indices") {
using OT1RI = pfor::expr::OperandTag<class ID1, R, decltype(pfor::ctv<2>*it)>;
using OT2RI = pfor::expr::OperandTag<class ID2, R, decltype(pfor::ctv<2>*it)>;
using OT3RI = pfor::expr::OperandTag<class ID3, R, decltype(pfor::ctv<2>*it)>;
using OT1WI = pfor::expr::OperandTag<class ID1, W, decltype(pfor::ctv<2>*it+pfor::ctv<1>)>;
using OT2WI = pfor::expr::OperandTag<class ID2, W, decltype(pfor::ctv<2>*it+pfor::ctv<1>)>;
using OT3WI = pfor::expr::OperandTag<class ID3, W, decltype(pfor::ctv<2>*it+pfor::ctv<1>)>;
using Tags1 = pfor::Pack<OT1RI, OT1WI, OT2RI, OT2WI, OT3RI, OT3WI>;
using Tags2 = pfor::Pack<OT1RI, OT1W>;
using Tags3 = pfor::Pack<OT1WI, OT1W>;
using Tags4 = pfor::Pack<OT1RI, OT1R>;
REQUIRE(pfor::rwControl<Tags1>);
REQUIRE_FALSE(pfor::rwControl<Tags2>);
REQUIRE_FALSE(pfor::rwControl<Tags3>);
REQUIRE(pfor::rwControl<Tags4>);
}
SECTION("Linear Diophantine Cases") {
using LD0 = decltype(pfor::ctv<2>*it);
using LD1 = decltype(it+pfor::ctv<5>);
using LD2 = decltype(pfor::ctv<2>*it+pfor::ctv<5>);
using Tags0 = pfor::Pack<pfor::expr::OperandTag<class ID0, R, LD0>, pfor::expr::OperandTag<class ID0, W, LD1>>;
using Tags1 = pfor::Pack<pfor::expr::OperandTag<class ID0, R, LD0>, pfor::expr::OperandTag<class ID0, W, LD2>>;
using Tags2 = pfor::Pack<pfor::expr::OperandTag<class ID0, R, LD1>, pfor::expr::OperandTag<class ID0, W, LD2>>;
REQUIRE_FALSE(pfor::rwControl<Tags0>);
REQUIRE(pfor::rwControl<Tags1>);
REQUIRE_FALSE(pfor::rwControl<Tags2>);
}
}
}