Skip to content

Commit 16bc367

Browse files
author
Mingsheng Hong
authored
---
yaml --- r: 262111 b: refs/heads/tensorflow c: 77e3dac h: refs/heads/master i: 262109: 0007dd2 262107: c6847cd 262103: bb8659d 262095: da308c3 262079: afcd55e
1 parent 7db1728 commit 16bc367

File tree

7 files changed

+115
-44
lines changed

7 files changed

+115
-44
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-04-25-a: 22f738a831d43aff2b9c9773bcb65
818818
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-05-08-a: 7d98cc16689baba5c8a3b90a9329bdcc1a12b4e9
819819
refs/heads/cherr42: a566ad54b073c2c56ac0a705d0a5bed9743135a5
820820
"refs/heads/codable_test_comment_fix": fc8f6824f7f347e1e8db55bff62db385c5728b5a
821-
refs/heads/tensorflow: 4d4f4b253ca9deb4fd12428b110c244e17d18164
821+
refs/heads/tensorflow: 77e3dac072dcba4b1be1fd5ec3e0099e76498044
822822
refs/tags/swift-4.1-DEVELOPMENT-SNAPSHOT-2018-05-11-a: 8126fd7a652e2f70ad6d76505239e34fb2ef3e1a
823823
refs/tags/swift-4.1-DEVELOPMENT-SNAPSHOT-2018-05-12-a: b3fd3dd84df6717f2e2e9df58c6d7e99fed57086
824824
refs/tags/swift-4.1-DEVELOPMENT-SNAPSHOT-2018-05-13-a: 71135119579039dc321c5f65d870050fe36efda2

branches/tensorflow/include/swift/Runtime/RuntimeFunctions.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,11 @@ FUNCTION(TFC_CreateFloatTensor, swift_tfc_CreateFloatTensor, C_CC,
14021402
ARGS(Int32Ty, Int8PtrTy, Int8PtrTy, Int8PtrTy),
14031403
ATTRS(NoUnwind))
14041404

1405+
FUNCTION(TFC_CreateScalarStringTensor, swift_tfc_CreateScalarStringTensor, C_CC,
1406+
RETURNS(Int8PtrTy),
1407+
ARGS(Int8PtrTy, Int32Ty, Int8PtrTy),
1408+
ATTRS(NoUnwind))
1409+
14051410
FUNCTION(TFE_Execute, swift_tfc_TFE_Execute, C_CC,
14061411
RETURNS(VoidTy),
14071412
ARGS(Int8PtrTy, Int8PtrPtrTy, Int32PtrTy, Int8PtrTy),

branches/tensorflow/lib/IRGen/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
if(SWIFT_ENABLE_TENSORFLOW)
2+
find_package(TensorFlow REQUIRED)
3+
include_directories(BEFORE "${TF_INCLUDE_DIR}")
4+
endif()
5+
16
add_swift_host_library(swiftIRGen STATIC
27
AllocStackHoisting.cpp
38
ClassLayout.cpp

branches/tensorflow/lib/IRGen/IRGenSIL.cpp

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
#include "swift/SIL/SILModule.h"
5050
#include "swift/SIL/SILType.h"
5151
#include "swift/SIL/SILVisitor.h"
52+
// SWIFT_ENABLE_TENSORFLOW
53+
#include "tensorflow/c/c_api.h"
5254
#include "clang/AST/ASTContext.h"
5355
#include "clang/Basic/TargetInfo.h"
5456
#include "clang/CodeGen/CodeGenABITypes.h"
@@ -2671,9 +2673,6 @@ void IRGenSILFunction::visitGraphOperationInst(GraphOperationInst *i) {
26712673
assert(0 && "dtype attr must have been processed!");
26722674
}
26732675

2674-
if (attr.value.getKind() == SymbolicValue::String)
2675-
assert(0 && "TODO: support string typed tensor attr.");
2676-
26772676
auto addScalar = [&](SymbolicValue value,
26782677
SmallVectorImpl<SymbolicValue> &elements) -> bool {
26792678
value = value.lookThroughSingleElementAggregates();
@@ -2686,6 +2685,7 @@ void IRGenSILFunction::visitGraphOperationInst(GraphOperationInst *i) {
26862685
SmallVector<SymbolicValue, 4> elements;
26872686
bool isFloat = false;
26882687
SmallVector<int64_t, 4> shape;
2688+
llvm::Value *tensor = nullptr;
26892689
// The scalar case is very simple, the shape of a scalar is 0d, and the
26902690
// data type comes from an attr that should already be processed.
26912691
auto attrValue = attr.value.lookThroughSingleElementAggregates();
@@ -2695,6 +2695,14 @@ void IRGenSILFunction::visitGraphOperationInst(GraphOperationInst *i) {
26952695
isFloat = (attrValue.getKind() == SymbolicValue::Float);
26962696
if (addScalar(attrValue, elements))
26972697
assert(0 && "Bad scalar value for tensor attr.");
2698+
2699+
if (attrValue.getKind() == SymbolicValue::String) {
2700+
auto str = attrValue.getStringValue();
2701+
auto strVal = IGM.getAddrOfGlobalString(str);
2702+
auto strLen = llvm::ConstantInt::get(IGM.Int32Ty, str.size());
2703+
auto *createTensorFn = IGM.getTFC_CreateScalarStringTensorFn();
2704+
tensor = Builder.CreateCall(createTensorFn, {strVal, strLen, status});
2705+
}
26982706
} else {
26992707
// Add all the elements to the elements list.
27002708
CanType eltType;
@@ -2706,8 +2714,11 @@ void IRGenSILFunction::visitGraphOperationInst(GraphOperationInst *i) {
27062714
LLVM_DEBUG(llvm::dbgs()
27072715
<< "The elt dtype of tensor-typed attr is " << eltType
27082716
<< ", with tfDtype = " << tfDtype << ".\n");
2709-
// 1 means TF_FLOAT.
2710-
isFloat = tfDtype == 1;
2717+
isFloat = tfDtype == TF_FLOAT;
2718+
2719+
// String tensors are usually to represent metadata like file names in a
2720+
// dataset TF op, so scalar tensor support above should be sufficient.
2721+
assert(tfDtype != TF_STRING && "Only support scalar string tensors.");
27112722

27122723
// Decode the shape attribute which must come next.
27132724
auto shapeAttr = i->getAttribute(nextAttributeNumber++).value;
@@ -2719,45 +2730,49 @@ void IRGenSILFunction::visitGraphOperationInst(GraphOperationInst *i) {
27192730

27202731
// Create llvm values for elements and shape, and then call
27212732
// swift_tfc_CreateIntTensor() or swift_tfc_CreateFloatTensor().
2722-
Address tensorEltVals;
2723-
createArrayAndSize<SymbolicValue>(
2724-
elements, isFloat ? IGM.FloatTy : IGM.Int64Ty, "tensorEltVals",
2725-
[&](SymbolicValue elt) {
2726-
return isFloat ? llvm::ConstantFP::get(
2727-
IGM.FloatTy,
2728-
(double)elt.getFloatValue().convertToFloat())
2729-
: llvm::ConstantInt::get(IGM.Int64Ty,
2730-
elt.getIntegerValue()
2731-
.sextOrTrunc(64)
2732-
.getLimitedValue());
2733-
},
2734-
tensorEltVals);
2735-
2736-
// Create the LLVM values representing shape.
2737-
Address dimVals;
2738-
llvm::Value *numDims = createArrayAndSize<int64_t>(
2739-
shape, IGM.Int64Ty, "dimVals",
2740-
[&](int64_t elt) { return llvm::ConstantInt::get(IGM.Int64Ty, elt); },
2741-
dimVals);
2742-
2743-
auto dimValsUntyped =
2744-
Builder.CreateBitCast(dimVals.getAddress(), IGM.Int8PtrTy);
2745-
auto tensorEltValsUntyped =
2746-
Builder.CreateBitCast(tensorEltVals.getAddress(), IGM.Int8PtrTy);
2747-
llvm::Value *tensor = nullptr;
2748-
if (isFloat) {
2749-
auto *createTensorFn = IGM.getTFC_CreateFloatTensorFn();
2750-
tensor =
2751-
Builder.CreateCall(createTensorFn, {numDims, dimValsUntyped,
2752-
tensorEltValsUntyped, status});
2753-
} else {
2754-
auto *createTensorFn = IGM.getTFC_CreateIntTensorFn();
2755-
auto dtypeVal = llvm::ConstantInt::get(IGM.Int32Ty, dtypeAttr);
2756-
tensor = Builder.CreateCall(
2757-
createTensorFn,
2758-
{numDims, dimValsUntyped, tensorEltValsUntyped, dtypeVal, status});
2733+
if (!tensor) {
2734+
Address tensorEltVals;
2735+
createArrayAndSize<SymbolicValue>(
2736+
elements, isFloat ? IGM.FloatTy : IGM.Int64Ty, "tensorEltVals",
2737+
[&](SymbolicValue elt) {
2738+
return isFloat ? llvm::ConstantFP::get(
2739+
IGM.FloatTy,
2740+
(double)elt.getFloatValue().convertToFloat())
2741+
: llvm::ConstantInt::get(IGM.Int64Ty,
2742+
elt.getIntegerValue()
2743+
.sextOrTrunc(64)
2744+
.getLimitedValue());
2745+
},
2746+
tensorEltVals);
2747+
2748+
// Create the LLVM values representing shape.
2749+
Address dimVals;
2750+
llvm::Value *numDims = createArrayAndSize<int64_t>(
2751+
shape, IGM.Int64Ty, "dimVals",
2752+
[&](int64_t elt) {
2753+
return llvm::ConstantInt::get(IGM.Int64Ty, elt);
2754+
},
2755+
dimVals);
2756+
2757+
auto dimValsUntyped =
2758+
Builder.CreateBitCast(dimVals.getAddress(), IGM.Int8PtrTy);
2759+
auto tensorEltValsUntyped =
2760+
Builder.CreateBitCast(tensorEltVals.getAddress(), IGM.Int8PtrTy);
2761+
if (isFloat) {
2762+
auto *createTensorFn = IGM.getTFC_CreateFloatTensorFn();
2763+
tensor = Builder.CreateCall(
2764+
createTensorFn,
2765+
{numDims, dimValsUntyped, tensorEltValsUntyped, status});
2766+
} else {
2767+
auto *createTensorFn = IGM.getTFC_CreateIntTensorFn();
2768+
auto dtypeVal = llvm::ConstantInt::get(IGM.Int32Ty, dtypeAttr);
2769+
tensor = Builder.CreateCall(createTensorFn,
2770+
{numDims, dimValsUntyped,
2771+
tensorEltValsUntyped, dtypeVal, status});
2772+
}
2773+
checkOk(status);
27592774
}
2760-
checkOk(status);
2775+
assert(tensor != nullptr);
27612776

27622777
// Set up the tensor-typed value attr as in:
27632778
// TFE_OpSetAttrTensor(op, "value", tensor, status);

branches/tensorflow/stdlib/public/CTensorFlow/ctensorflow_init.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "tensorflow/core/platform/init_main.h"
77

88
#include <assert.h>
9+
#include <stdio.h>
10+
#include <stdlib.h>
911
#include <vector>
1012

1113
extern "C" {
@@ -128,6 +130,35 @@ void *swift_tfc_CreateFloatTensor(int32_t num_dims, int64_t *dims, float *vals,
128130
return tensor;
129131
}
130132

133+
/// A default deallocator function to pass in `TF_NewTensor`.
134+
static void tensorDataDeallocator(void *data, size_t len, void *arg) {
135+
free(data);
136+
};
137+
138+
// Also see convertValuesToTensor() in TFLowerGraph.cpp
139+
void *swift_tfc_CreateScalarStringTensor(char *val, int32_t valLen,
140+
TF_Status *status) {
141+
// printf is kept for debugging purposes.
142+
// printf("string val: %s, with len %d \n", val, valLen);
143+
144+
size_t offsetsSize = sizeof(uint64_t);
145+
size_t totalSize = offsetsSize + TF_StringEncodedSize(valLen);
146+
147+
totalSize += offsetsSize;
148+
149+
void *baseAddr = malloc(totalSize);
150+
auto *tensor =
151+
TF_NewTensor(TF_STRING, /*dims*/ nullptr, /*num_dims*/ 0, baseAddr,
152+
totalSize, tensorDataDeallocator, nullptr);
153+
154+
uint64_t *offsets = (uint64_t *)baseAddr;
155+
*offsets = 0;
156+
char *dataStart = (char *)baseAddr + offsetsSize;
157+
(void)TF_StringEncode(val, valLen, dataStart, totalSize, status);
158+
159+
return tensor;
160+
}
161+
131162
void swift_tfc_TFE_Execute(void *op, void **retvals, int32_t *num_retvals,
132163
void *status) {
133164
int int_num_retvals = *num_retvals;

branches/tensorflow/stdlib/public/CTensorFlow/ctensorflow_init.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ void *swift_tfc_CreateIntTensor(int32_t num_dims, int64_t *dims, int64_t *vals,
3737
void *swift_tfc_CreateFloatTensor(int32_t num_dims, int64_t *dims, float *vals,
3838
TF_Status *status);
3939

40+
// Similar to the above API, but creates a scalar string tensor.
41+
void *swift_tfc_CreateScalarStringTensor(char *val, int32_t valLen,
42+
TF_Status *status);
43+
4044
void swift_tfc_TFE_Execute(void *op, void **retvals, int32_t *num_retvals,
4145
void *status);
4246

branches/tensorflow/test/TensorFlowRuntime/dynamic_attributes.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,15 @@ DynamicAttributeTests.testAllBackends("ShapeAttribute TensorShape? nil") {
404404
expectEqual(t, result)
405405
}
406406

407+
// A tensor typed attribute with a scalar string value
408+
DynamicAttributeTests.testAllBackends("StringTensorAttribute SR-9555") {
409+
func foo() {
410+
_ = StringTensor("string")
411+
}
412+
413+
withDevice(.cpu) {
414+
foo()
415+
}
416+
}
417+
407418
runAllTests()

0 commit comments

Comments
 (0)