Commit c52f9f7a by liyinqiao

Support fp16 data type for more operations and fix the minor errors.

parent 1f1413ca
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2018, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2018, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2018, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2018, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2018, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2018, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
...@@ -55,6 +55,8 @@ namespace nts { ...@@ -55,6 +55,8 @@ namespace nts {
#define DTYPE_MIN (DTYPE)-3.40E+38 #define DTYPE_MIN (DTYPE)-3.40E+38
#endif #endif
#define MY_HALF_MIN 6.10E-5
#define LOGPROB_MIN (DTYPE)-2E+1 #define LOGPROB_MIN (DTYPE)-2E+1
#define GRAD_MAX (DTYPE)1E+5 #define GRAD_MAX (DTYPE)1E+5
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
...@@ -254,6 +254,9 @@ template <typename T> ...@@ -254,6 +254,9 @@ template <typename T>
void TensorListBase<T>::Clear() void TensorListBase<T>::Clear()
{ {
count = 0; count = 0;
delete[] items;
maxNum = 0;
items = NULL;
} }
/* /*
...@@ -288,12 +291,13 @@ inline void TensorListBase<T>::Reverse() ...@@ -288,12 +291,13 @@ inline void TensorListBase<T>::Reverse()
/* remove the item at position i */ /* remove the item at position i */
template <typename T> template <typename T>
void TensorListBase<T>::Remove(int i) void TensorListBase<T>::Remove(int idx)
{ {
if (i >= count || i < 0) CheckNTErrors(idx < count && idx > -1, "invalid index");
return;
memcpy(items + i, items + i + 1, sizeof(T*) * (count - i - 1)); for (int i = idx; i < count - 1; i++) {
items[i] = items[i + 1];
}
count--; count--;
} }
...@@ -355,6 +359,20 @@ void TensorListBase<T>::Shuffle(int nround, int beg, int len) ...@@ -355,6 +359,20 @@ void TensorListBase<T>::Shuffle(int nround, int beg, int len)
} }
} }
/* sum a range of values */
template<>
int TensorListBase<int>::SumRange(int begin, int end)
{
CheckNTErrors(begin < count && end <= count && end > begin, "invalid index of begin or end");
int value = items[begin];
int i = begin + 1;
while (i < end) {
value += items[i];
i++;
}
return value;
}
/* specializations and typedef of list */ /* specializations and typedef of list */
template struct TensorListBase<int>; template struct TensorListBase<int>;
template struct TensorListBase<char>; template struct TensorListBase<char>;
......
...@@ -130,6 +130,9 @@ public: ...@@ -130,6 +130,9 @@ public:
}; };
T& Get(int i) { return GetItem(i); }; T& Get(int i) { return GetItem(i); };
void Set(int i, T item) { SetItem(i, item); }; void Set(int i, T item) { SetItem(i, item); };
/* sum a range of values */
T SumRange(int begin, int end);
}; };
struct XTensor; struct XTensor;
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
...@@ -1583,16 +1583,16 @@ MTYPE XMemManager::GetAvailableGPUMemory(int devID) ...@@ -1583,16 +1583,16 @@ MTYPE XMemManager::GetAvailableGPUMemory(int devID)
void XMemManager::GetBufferSize(MTYPE freeMem, MTYPE * myBufSize) void XMemManager::GetBufferSize(MTYPE freeMem, MTYPE * myBufSize)
{ {
*myBufSize = 0; *myBufSize = 0;
if (freeMem >= MILLION * 128){ if (freeMem >= MILLION * 128ULL){
*myBufSize = MILLION * 32; *myBufSize = MILLION * 32ULL;
if (freeMem >= MILLION * 256){ if (freeMem >= MILLION * 256ULL){
*myBufSize = MILLION * 64; *myBufSize = MILLION * 64ULL;
if (freeMem >= MILLION * 512){ if (freeMem >= MILLION * 512ULL){
*myBufSize = MILLION * 128; *myBufSize = MILLION * 128ULL;
if (freeMem >= MILLION * 1024) { if (freeMem >= MILLION * 1024ULL) {
*myBufSize = MILLION * 128; *myBufSize = MILLION * 128ULL;
if (freeMem >= MILLION * 2048) if (freeMem >= MILLION * 2048ULL)
*myBufSize = MILLION * 128; *myBufSize = MILLION * 128ULL;
} }
} }
} }
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2018, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2018, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "core/getandset/SetData.h" #include "core/getandset/SetData.h"
#include "function/Identity.h" #include "function/Identity.h"
#include "core/CHeader.h" #include "core/CHeader.h"
//#include "XHalf.hpp"
#ifdef USE_CUDA #ifdef USE_CUDA
...@@ -179,11 +180,13 @@ XTensor::XTensor(const XTensor& reference) ...@@ -179,11 +180,13 @@ XTensor::XTensor(const XTensor& reference)
_CopyValues(&reference, this); _CopyValues(&reference, this);
} }
if(reference.isTmp) if (reference.enableGrad) {
XLink::Replace(&reference, this); if (reference.isTmp)
else{ XLink::Replace(&reference, this);
CheckNTErrors(outgo.tailNum == 0, "The node has outgoing edge to other nodes!"); else {
XLink::CopyIncoming(&reference, this); CheckNTErrors(outgo.tailNum == 0, "The node has outgoing edge to other nodes!");
XLink::CopyIncoming(&reference, this);
}
} }
isInit = true; isInit = true;
...@@ -212,7 +215,9 @@ XTensor::XTensor(const XTensor&& reference) ...@@ -212,7 +215,9 @@ XTensor::XTensor(const XTensor&& reference)
This is VERY tricky and there might be better solutions :) */ This is VERY tricky and there might be better solutions :) */
*reference.dataP = NULL; *reference.dataP = NULL;
XLink::Replace(&reference, this); if (reference.enableGrad) {
XLink::Replace(&reference, this);
}
isInit = true; isInit = true;
isTmp = reference.isTmp; isTmp = reference.isTmp;
...@@ -234,13 +239,15 @@ XTensor::~XTensor() ...@@ -234,13 +239,15 @@ XTensor::~XTensor()
newTensor->SetTMPFlag(); newTensor->SetTMPFlag();
newTensor->data = data; newTensor->data = data;
data = NULL; data = NULL;
XLink::Replace(this, newTensor); if (enableGrad)
XLink::Replace(this, newTensor);
}
if (enableGrad) {
XLink::ClearOutgoing(this);
XLink::ClearIncoming(this);
} }
XLink::ClearOutgoing(this);
XLink::ClearIncoming(this);
DestroyData(); DestroyData();
if(grad != NULL) if(grad != NULL)
...@@ -341,9 +348,11 @@ XTensor& XTensor::operator= (const XTensor& tensor) ...@@ -341,9 +348,11 @@ XTensor& XTensor::operator= (const XTensor& tensor)
newTensor->dataHost = dataHost; newTensor->dataHost = dataHost;
newTensor->signature = tensor.signature; newTensor->signature = tensor.signature;
XLink::Replace(this, newTensor); if (enableGrad) {
XLink::ClearOutgoing(this); XLink::Replace(this, newTensor);
XLink::ClearIncoming(this); XLink::ClearOutgoing(this);
XLink::ClearIncoming(this);
}
newTensor->ShallowCopy(this); newTensor->ShallowCopy(this);
data = NULL; data = NULL;
...@@ -354,15 +363,19 @@ XTensor& XTensor::operator= (const XTensor& tensor) ...@@ -354,15 +363,19 @@ XTensor& XTensor::operator= (const XTensor& tensor)
/* NOTE: this might lead to additional data copy by Mac LLVM compilers */ /* NOTE: this might lead to additional data copy by Mac LLVM compilers */
/* we make an identity transformation here */ /* we make an identity transformation here */
if(outgo.tailNum > 0) if (enableGrad) {
XLink::ClearOutgoing(this); if (outgo.tailNum > 0)
XLink::ClearIncoming(this); XLink::ClearOutgoing(this);
XLink::ClearIncoming(this);
}
if(!_IsSameShaped(this, &tensor)) if(!_IsSameShaped(this, &tensor))
Resize(tensor.order, tensor.dimSize, tensor.dataType, tensor.denseRatio); Resize(tensor.order, tensor.dimSize, tensor.dataType, tensor.denseRatio);
_Identity(&tensor, this); _Identity(&tensor, this);
XLink::MakeLink(&tensor, NULL, this, FUNC_IDENTITY); if (enableGrad) {
XLink::MakeLink(&tensor, NULL, this, FUNC_IDENTITY);
}
} }
else{ else{
/* hard copy of the data array */ /* hard copy of the data array */
...@@ -396,7 +409,9 @@ XTensor& XTensor::operator= (const XTensor& tensor) ...@@ -396,7 +409,9 @@ XTensor& XTensor::operator= (const XTensor& tensor)
CheckNTErrors(outgo.tailNum == 0, "The node has outgoing edge to other nodes!"); CheckNTErrors(outgo.tailNum == 0, "The node has outgoing edge to other nodes!");
/* create tensor links for the new tensor */ /* create tensor links for the new tensor */
XLink::Copy(&tensor, this); if (enableGrad) {
XLink::Copy(&tensor, this);
}
} }
return *this; return *this;
...@@ -418,9 +433,11 @@ XTensor& XTensor::operator= (const XTensor&& tensor) ...@@ -418,9 +433,11 @@ XTensor& XTensor::operator= (const XTensor&& tensor)
newTensor->dataHost = dataHost; newTensor->dataHost = dataHost;
newTensor->signature = tensor.signature; newTensor->signature = tensor.signature;
XLink::Replace(this, newTensor); if (enableGrad) {
XLink::ClearOutgoing(this); XLink::Replace(this, newTensor);
XLink::ClearIncoming(this); XLink::ClearOutgoing(this);
XLink::ClearIncoming(this);
}
newTensor->ShallowCopy(this); newTensor->ShallowCopy(this);
data = NULL; data = NULL;
...@@ -444,7 +461,9 @@ XTensor& XTensor::operator= (const XTensor&& tensor) ...@@ -444,7 +461,9 @@ XTensor& XTensor::operator= (const XTensor&& tensor)
This is VERY tricky and there might be better solutions :) */ This is VERY tricky and there might be better solutions :) */
*tensor.dataP = NULL; *tensor.dataP = NULL;
XLink::Copy(&tensor, this); if (enableGrad) {
XLink::Copy(&tensor, this);
}
return *this; return *this;
} }
...@@ -1697,6 +1716,17 @@ void XTensor::Dump(FILE* file, const char* label, const int n, const int beg, co ...@@ -1697,6 +1716,17 @@ void XTensor::Dump(FILE* file, const char* label, const int n, const int beg, co
fprintf(file, " %d", f); fprintf(file, " %d", f);
} }
} }
/*else if (dataType == X_FLOAT16) {
int end = MIN(n > 0 ? beg + n : beg + unitNum, unitNum);
for(int i = beg; i < end; i++){
DTYPE f = ((half_float::half*)d)[i];
if(i == beg)
fprintf(file, "%e", f);
else
fprintf(file, " %e", f);
}
}*/
else else
ShowNTErrors("TODO!"); ShowNTErrors("TODO!");
} }
...@@ -1749,12 +1779,17 @@ void XTensor::BinaryDump(FILE* file) ...@@ -1749,12 +1779,17 @@ void XTensor::BinaryDump(FILE* file)
_CopyValues(this, &tmp); _CopyValues(this, &tmp);
switch (dataType) { switch (dataType) {
case X_INT: { case X_INT: {
fwrite(tmp.data, sizeof(int), unitNum, file); fwrite(tmp.data, sizeof(int), unitNum, file);
} break;
default: { }
fwrite(tmp.data, sizeof(float), unitNum, file); /*case X_FLOAT16: {
} fwrite(tmp.data, sizeof(half_float::half), unitNum, file);
break;
}*/
default: {
fwrite(tmp.data, sizeof(float), unitNum, file);
}
} }
} }
...@@ -1877,20 +1912,27 @@ read data from a binary file ...@@ -1877,20 +1912,27 @@ read data from a binary file
*/ */
void XTensor::BinaryRead(FILE* file, size_t offset) void XTensor::BinaryRead(FILE* file, size_t offset)
{ {
fseek(file, offset, 0);
switch (dataType) { switch (dataType) {
case X_INT: { case X_INT: {
int* d = new int[unitNum]; int* d = new int[unitNum];
fread(d, sizeof(int), unitNum, file); fread(d, sizeof(int), unitNum, file);
SetData(d, unitNum); SetData(d, unitNum);
delete[] d; delete[] d;
} break;
default: { }
float* d = new float[unitNum]; /*case X_FLOAT16: {
fread(d, sizeof(float), unitNum, file); half_float::half* d = new half_float::half[unitNum];
SetData(d, unitNum); fread(d, sizeof(half_float::half), unitNum, file);
delete[] d; SetData(d, unitNum);
} delete[] d;
break;
}*/
default: {
float* d = new float[unitNum];
fread(d, sizeof(float), unitNum, file);
SetData(d, unitNum);
delete[] d;
}
} }
} }
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
...@@ -175,7 +175,7 @@ public: ...@@ -175,7 +175,7 @@ public:
XLink outgo; XLink outgo;
/******************** /********************
XTensor untilities XTensor utilities
********************/ ********************/
/* constructor */ /* constructor */
...@@ -440,7 +440,7 @@ public: ...@@ -440,7 +440,7 @@ public:
void Read(FILE * file, const char * label = NULL); void Read(FILE * file, const char * label = NULL);
/* read data from a binary file */ /* read data from a binary file */
void BinaryRead(FILE * file, size_t offset); void BinaryRead(FILE * file, size_t offset = 0);
/* flush the data to the target device */ /* flush the data to the target device */
void FlushToMem(XMem * targetMem); void FlushToMem(XMem * targetMem);
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
/* NiuTrans.Tensor - an open-source tensor library /* NiuTrans.Tensor - an open-source tensor library
* Copyright (C) 2017, Natural Language Processing Lab, Northeastern University. * Copyright (C) 2017, Natural Language Processing Lab, Northeastern University.
* All rights reserved. * All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论