place.h 7.7 KB
Newer Older
1
/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

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 <string>

19 20
#include "paddle/phi/api/include/dll_decl.h"

21 22 23 24
namespace paddle {
enum class PlaceType;
}

25
namespace phi {
26 27

enum class AllocationType : int8_t {
28
  UNDEFINED = 0,
29 30 31 32 33 34 35 36
  CPU = 1,
  GPU = 2,
  GPUPINNED = 3,
  XPU = 4,
  NPU = 5,
  NPUPINNED = 6,
  IPU = 7,
  MLU = 8,
37
  CUSTOM = 9,
38
};
39

40
const char* AllocationTypeStr(AllocationType type);
41

42 43 44 45
PADDLE_API size_t
GetOrRegisterGlobalDeviceTypeId(const std::string& device_type);

PADDLE_API std::string GetGlobalDeviceType(size_t device_type_id_);
46

47
/// \brief The place is used to specify where the data is stored.
48
class PADDLE_API Place {
49
 public:
50
  Place() : device(0), alloc_type_(AllocationType::UNDEFINED) {}
51

52 53 54 55 56 57 58 59 60 61 62 63
  explicit Place(AllocationType type,
                 int8_t id,
                 const std::string& dev_type = "")
      : device(id),
        alloc_type_(type),
        device_type_id_(GetOrRegisterGlobalDeviceTypeId(dev_type)) {}

  explicit Place(AllocationType type, const std::string& dev_type = "")
      : device(0),
        alloc_type_(type),
        device_type_id_(GetOrRegisterGlobalDeviceTypeId(dev_type)) {}

64 65 66
  // See NOTE [ Why need to temporarily adapt to PlaceType? ]
  Place(paddle::PlaceType type);  // NOLINT

67 68 69
  void Reset(AllocationType type,
             int8_t device_id = 0,
             const std::string& dev_type = "") noexcept {
70 71
    alloc_type_ = type;
    device = device_id;
72 73 74
    if (!dev_type.empty()) {
      device_type_id_ = GetOrRegisterGlobalDeviceTypeId(dev_type);
    }
75 76
  }

77
  AllocationType GetType() const { return alloc_type_; }
78

79
  int8_t GetDeviceId() const { return device; }
80

81 82 83 84
  std::string GetDeviceType() const {
    return GetGlobalDeviceType(device_type_id_);
  }

85 86
  std::string DebugString() const;

87 88 89 90 91 92 93 94 95
  struct Hash {
    // Note: Now the number of bits we need does not exceed 32 bits, so there is
    // no need to use 64 bits. If needed in the future, it can be expanded,
    // but now we don’t over-design.
    uint32_t operator()(const Place& place) const;
  };

  uint32_t HashValue() const { return Hash()(*this); }

96
  inline bool operator==(const Place& rhs) const {
97 98 99 100
    return HashValue() == rhs.HashValue();
  }
  inline bool operator!=(const Place& rhs) const {
    return HashValue() != rhs.HashValue();
101 102
  }
  inline bool operator<(const Place& rhs) const {
103
    return HashValue() < rhs.HashValue();
104 105
  }

106 107 108
 public:
  // TODO(wilber): Just because of backward compatibility, it needs to be
  // changed to private in the future.
109
  int8_t device{0};
110 111

 private:
112
  AllocationType alloc_type_{AllocationType::UNDEFINED};
113
  size_t device_type_id_;
114 115 116 117
};

class CPUPlace : public Place {
 public:
118 119 120 121
  CPUPlace() : Place(AllocationType::CPU) {}

  CPUPlace(const CPUPlace&) = default;
  CPUPlace(const Place& place) : Place(AllocationType::CPU) {}  // NOLINT
122 123 124 125 126 127
};

class GPUPlace : public Place {
 public:
  GPUPlace() : Place(AllocationType::GPU, 0) {}
  explicit GPUPlace(int device_id) : Place(AllocationType::GPU, device_id) {}
128 129 130 131

  GPUPlace(const GPUPlace&) = default;
  GPUPlace(const Place& place)  // NOLINT
      : Place(AllocationType::GPU, place.GetDeviceId()) {}
132 133 134 135 136
};

class GPUPinnedPlace : public Place {
 public:
  GPUPinnedPlace() : Place(AllocationType::GPUPINNED) {}
137 138 139 140

  GPUPinnedPlace(const GPUPinnedPlace&) = default;
  GPUPinnedPlace(const Place& place)  // NOLINT
      : Place(AllocationType::GPUPINNED) {}
141 142 143 144 145 146
};

class XPUPlace : public Place {
 public:
  XPUPlace() : Place(AllocationType::XPU, 0) {}
  explicit XPUPlace(int device_id) : Place(AllocationType::XPU, device_id) {}
147 148 149 150

  XPUPlace(const XPUPlace&) = default;
  XPUPlace(const Place& place)  // NOLINT
      : Place(AllocationType::XPU, place.GetDeviceId()) {}
151 152 153 154 155
};

class NPUPlace : public Place {
 public:
  NPUPlace() : Place(AllocationType::NPU, 0) {}
156 157 158 159 160
  explicit NPUPlace(int device_id) : Place(AllocationType::NPU, device_id) {}

  NPUPlace(const NPUPlace&) = default;
  NPUPlace(const Place& place)  // NOLINT
      : Place(AllocationType::NPU, place.GetDeviceId()) {}
161 162 163 164 165
};

class NPUPinnedPlace : public Place {
 public:
  NPUPinnedPlace() : Place(AllocationType::NPUPINNED) {}
166 167 168 169

  NPUPinnedPlace(const NPUPinnedPlace&) = default;
  NPUPinnedPlace(const Place& place)  // NOLINT
      : Place(AllocationType::NPUPINNED) {}
170 171 172 173
};

class IPUPlace : public Place {
 public:
174 175 176 177 178 179
  IPUPlace() : Place(AllocationType::IPU, 0) {}
  explicit IPUPlace(int device_id) : Place(AllocationType::IPU, device_id) {}

  IPUPlace(const IPUPlace&) = default;
  IPUPlace(const Place& place)  // NOLINT
      : Place(AllocationType::IPU, place.GetDeviceId()) {}
180 181 182 183 184 185
};

class MLUPlace : public Place {
 public:
  MLUPlace() : Place(AllocationType::MLU, 0) {}
  explicit MLUPlace(int device_id) : Place(AllocationType::MLU, device_id) {}
186 187 188 189

  MLUPlace(const MLUPlace&) = default;
  MLUPlace(const Place& place)  // NOLINT
      : Place(AllocationType::MLU, place.GetDeviceId()) {}
190 191
};

192 193
class CustomPlace : public Place {
 public:
194
  CustomPlace() : Place(AllocationType::CUSTOM, 0, "") {}
195 196 197 198 199 200 201 202 203 204 205 206 207 208
  explicit CustomPlace(const std::string dev_type)
      : Place(AllocationType::CUSTOM, 0, dev_type) {}
  CustomPlace(const std::string dev_type, int device_id)
      : Place(AllocationType::CUSTOM, device_id, dev_type) {}

  CustomPlace(const CustomPlace&) = default;
  CustomPlace(const Place& place) {  // NOLINT
    if (place.GetType() == AllocationType::CUSTOM) {
      this->Reset(
          AllocationType::CUSTOM, place.GetDeviceId(), place.GetDeviceType());
    }
  }
};

209
std::ostream& operator<<(std::ostream&, const Place&);
210

211
}  // namespace phi
212 213 214 215 216

namespace paddle {
namespace experimental {
using AllocationType = phi::AllocationType;
using Place = phi::Place;
217 218 219 220 221
using CPUPlace = phi::CPUPlace;
using GPUPlace = phi::GPUPlace;
using GPUPinnedPlace = phi::GPUPinnedPlace;
using XPUPlace = phi::XPUPlace;
using NPUPlace = phi::NPUPlace;
222
}  // namespace experimental
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261

using AllocationType = phi::AllocationType;
using Place = phi::Place;
using CPUPlace = phi::CPUPlace;
using GPUPlace = phi::GPUPlace;

/* NOTE [ Why need to temporarily adapt to PlaceType? ]

`PlaceType` emum class is the place type used by custom operators since the
release of 2.0. Since 2.3, we have refactored the operator library and designed
a new external Place type. The original PlaceType is no longer suitable for use
as an internal type of the framework, but immediately delete the PlaceType,
it will cause the previous custom operators to be incompatible, so it cannot be
deleted in the short term. We'd better delete this abandoned data type in 2.4.

Note: This type cannot add any new type!!! It is only used for compatibility
with
historical writing and we will remove this temporary type in the future.
This Type cannot be used in framework! only used for custom operator!

The original PlaceType define:

- enum class PlaceType { kUNK = -1, kCPU, kGPU };

The historical PlaceType using:

- PD_CHECK(x.place() == paddle::PlaceType::kCPU)
- auto out = paddle::Tensor(paddle::PlaceType::kCPU, x.shape());

*/
enum class PlaceType {
  kUNK = static_cast<int>(phi::AllocationType::UNDEFINED),
  kCPU = static_cast<int>(phi::AllocationType::CPU),
  kGPU = static_cast<int>(phi::AllocationType::GPU),
};

PADDLE_API bool operator==(const Place& place, PlaceType place_type);
PADDLE_API bool operator==(PlaceType place_type, const Place& place);

262
}  // namespace paddle